android - 将图像存储在服务器上以与 Android 应用程序一起使用的大小

标签 android listview bitmap imageview

我有一个允许用户上传个人资料照片的 Android 应用程序。它们以 300px X 300px 的大小存储在服务器上。

在应用程序中,我以 40dp X 40dp 或有时 100dp X 100dp 使用它们。 40dp 的图像在 ListView 中。实际上,我使用非常流行的第三方 LazyList 将图像(使用 ImageLoader 类)存储在缓存中。 Here is the exact library .

我只是像这样在我的适配器中显示图像:

imageLoader.DisplayImage(profileUrl, holder.iv1);

我获取 Web URL 并将其直接显示到 ImageView 40dp x 40dp。

有时我会注意到图像质量下降。图像被部分加载的地方,然后被损坏。

一种理论认为,从服务器上的大图像开始并尝试将其存储在实际应用程序的一个小区域中,然后在 ListView 中多次执行此操作会导致一些加载问题.

问题:当服务器中的图像比您需要显示的大得多时,处理这种情况的最佳方法是什么?我假设我可能需要使用 BitMapFactory 或类似的类来构建新图像。但我不确定。我觉得我错过了一步。

这是一个 ListView 中的图像示例,该图像已损坏,请注意并非所有人都会发生这种情况。 (是的,他是来自 Arrested Development 的 Tobias。)

跟进:当图像来自服务器时,我们如何考虑 xxhdpixhdpi 等的文件大小而不是资源文件夹?

enter image description here

最佳答案

您正在使用的库看起来几乎不再维护(上次更新至少已有一年)。有几个更新的、可能更好的库可以解决同样的问题。我最喜欢的是Square's Picasso .使用起来非常简单,很好的解决了ListView里面的图片加载问题。

更直接地回答您的一些问题:

What is the best way to handle this situation when you have a much larger image in the server than you need to display?

您需要将位图二次采样到目标大小。谷歌对所有这些都有很好的描述 here .

首先,您必须解码位图,设置 inJustDecodeBounds bool 值以获得位图大小。

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;

然后您可以根据目标高度和宽度计算样本量。

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

然后您可以使用计算出的样本大小来加载向下采样的位图。最终代码看起来像

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

And how do we take in consideration file size for xxhdpi, xhdpi, etc when the image is coming from server and not the resources folder?

您可以使用以下代码段计算要将位图缩小到的目标像素大小:

float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, "10", context.getResources().getDisplayMetrics());

长话短说

使用Square's Picasso它将解决您所有的问题。

关于android - 将图像存储在服务器上以与 Android 应用程序一起使用的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23504708/

相关文章:

android - Toast 不从列表中的选定项目生成文本

android - 缩放位图以适合 Canvas

android - 请求码==400,尝试登录webservice

android - Android 图案锁定屏幕上的时钟字体

android - 如何使用 ListFragment 中的 ListView?

java - 使用 Glide 加载位图到 ImageView

在 C 中创建 BMP 文件(位图)

Android WallpaperManager 缩放位图太小

android - Java BufferedImage/Android 位图

android - ListView 中的微调器