Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在服务器上存储多大尺寸的图像以与Android应用程序配合使用_Android_Listview_Bitmap_Imageview - Fatal编程技术网

在服务器上存储多大尺寸的图像以与Android应用程序配合使用

在服务器上存储多大尺寸的图像以与Android应用程序配合使用,android,listview,bitmap,imageview,Android,Listview,Bitmap,Imageview,我有一个Android应用程序,允许用户上传个人资料图片。它们在服务器上存储为300px 300px 在这个应用程序中,我使用40dp X 40dp或有时使用100dp X 100dp。40dp的图像位于列表视图中。实际上,我使用非常流行的第三方LazyList将图像存储在缓存中(使用ImageLoader类) 我只需在我的适配器中显示图像,如下所示: imageLoader.DisplayImage(profileUrl, holder.iv1); 我获取web URL并将其直接显示在Ima

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

在这个应用程序中,我使用40dp X 40dp或有时使用100dp X 100dp。40dp的图像位于
列表视图中。实际上,我使用非常流行的第三方
LazyList
将图像存储在缓存中(使用
ImageLoader
类)

我只需在我的
适配器中显示图像,如下所示:

imageLoader.DisplayImage(profileUrl, holder.iv1);
我获取web URL并将其直接显示在
ImageView
40dp x 40dp中

有时我会注意到图像退化。如果图像部分加载,则图像已损坏

一种理论是,从服务器上的一个大图像开始,尝试将其存储在实际应用程序中的一个小区域中,然后在
列表视图中多次这样做,这会导致一些加载问题

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

下面是一个
列表视图
中的图像已损坏的示例,请注意,并非所有图像都已损坏。(是的,那是来自发展部的托比亚斯。)

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


我建议在用于请求图像的URL中添加一个参数(例如,
&size=small
),并让服务器保留每个图像的多个大小。这样做的一些好处是:

  • 减少应用程序中的数据使用量
  • 更好的图像质量(无需对图像重新采样)
  • 更好的性能(大型位图需要更长的加载时间)
  • 缺点是:

  • 更复杂(用于确定要请求的大小的逻辑)
  • 服务器上的更多存储要求
  • 我认为利大于弊,最终你会获得更好的用户体验

    在后续工作中,您甚至可以为每个密度(例如,
    &density=mdpi
    )设置参数,以提供适当的大小(并且您可以只打开
    getResources().getDisplayMetrics().densityDpi
    来获取参数值)

    例如:

    int densityDpi = getResources().getDisplayMetrics().densityDpi;
    if (densityDpi <= DisplayMetrics.DENSITY_MEDIUM) {
        return "mdpi";
    } else if (densityDpi <= DisplayMetrics.DENSITY_HIGH) {
        return "hdpi";
    } else if (densityDpi <= DisplayMetrics.DENSITY_XHIGH) {
        return "xhdpi";
    } else if (densityDpi <= DisplayMetrics.DENSITY_XXHIGH) {
        return "xxhdpi";
    } else {
        return "xxxhdpi";
    }
    
    int densityDpi=getResources().getDisplayMetrics().densityDpi;
    
    如果(densityDpi您正在使用的库看起来几乎不再维护(上次更新至少有一年了)。有几个更新的、可能更好的库可以解决相同的问题。我最喜欢的是。它使用非常简单,很好地解决了ListView中的图像加载问题

    要更直接地回答您的一些问题: 当你有很多钱的时候,处理这种情况的最好方法是什么 服务器中的图像是否比需要显示的图像大

    你需要对位图进行二次采样,直到达到目标大小。谷歌对所有这些都有很好的描述

    首先,您必须对位图进行解码,设置
    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;
    
    然后,您可以根据目标高度和宽度计算样本大小

    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);
    }
    
    当图像来自服务器而不是资源文件夹时,我们如何考虑xxhdpi、xhdpi等的文件大小

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

    float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, "10", context.getResources().getDisplayMetrics());
    
    太长,读不下去了
    使用它,它将解决您所有的问题。

    该库非常完美!仅此250分就值了!好吧,它几乎完美了,我希望有一种简单的方法来清除缓存。我确实看到了,但我不确定如何访问代码,因为它是一个jar文件。我确信我能找到它,但最终,我没有实现我需要这个函数,正如我所想的那样。不管怎样,听起来毕加索的人很快就会实现它。你只需要在com.squareup.Picasso包中创建毕加索工具类。这样你就可以访问包私有缓存。@jamesmcracken我正在使用毕加索resize with centrecrop,但我的recyclerview是挂起我的意思是图片已经被缓存了,但是recyclerview挂起了。你能告诉我可能的问题是什么,或者我应该用什么来代替调整大小吗??