在Android服务器上使用的服务器上存储图像的大小

The*_*ter 5 android listview bitmap imageview

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

在应用程序中,我使用它们40dp X 40dp或有时100dp X 100dp.40dp的图像都在ListView.我实际上使用非常受欢迎的第三方LazyList将图像(使用ImageLoader类)存储在缓存中. 这是确切的库.

我只是在我adapter这样显示图像:

imageLoader.DisplayImage(profileUrl, holder.iv1);
Run Code Online (Sandbox Code Playgroud)

我获取网址并将其直接显示在ImageView40dp x 40dp中.

有时我注意到图像质量下降 图像被部分加载,然后被破坏.

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

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

这是一个ListView已损坏的图像的示例,请注意这并非发生在所有人身上.(是的,这是来自Arrested Development的 Tobias .)

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

在此输入图像描述

Jam*_*ken 5

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

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

当您在服务器中拥有比您需要显示的图像大得多的图像时,处理这种情况的最佳方法是什么?

您需要将Bitmap子采样到目标大小.谷歌在这里对所有这些都做了很好的准备.

首先,您必须解码设置inJustDecodeBounds布尔值的位图以获取位图大小.

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;
Run Code Online (Sandbox Code Playgroud)

然后,您可以根据目标高度和宽度计算样本大小.

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;
}
Run Code Online (Sandbox Code Playgroud)

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, "10", context.getResources().getDisplayMetrics());
Run Code Online (Sandbox Code Playgroud)

TL; DR

使用Square的Picasso,它将解决您的所有问题.