Android 是否支持使用位图工厂选项的多个屏幕?
编辑一个: 根据Joseph的回答所做的更改: 在bytesToDrawablebyte[]imageBytes中: 更改了以下内容:使用BitmapDrawableResources res,位图位图代替BitmapDrawableBitmap位图:Android 是否支持使用位图工厂选项的多个屏幕?,android,android-emulator,module,screen,bitmapfactory,Android,Android Emulator,Module,Screen,Bitmapfactory,编辑一个: 根据Joseph的回答所做的更改: 在bytesToDrawablebyte[]imageBytes中: 更改了以下内容:使用BitmapDrawableResources res,位图位图代替BitmapDrawableBitmap位图: return new BitmapDrawable(ApplicationConstants.ref_currentActivity.getResources(),BitmapFactory.decodeByteArray(imageBytes,
return new BitmapDrawable(ApplicationConstants.ref_currentActivity.getResources(),BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, options));
这是这一变化的结果:略有不同的问题:
问题:
如果我正在使用位图可绘制的新构造函数,并且它根据所需的目标密度缩放图像,那么我还需要使用CalculatesSampleSize方法吗
原始问题:
嗨,朋友们
我的应用程序是基于模块的,因此特定于该模块的图像仅从包含它们的模块加载,而不是从主应用程序加载
每个模块都有自己的ModularImageLoader——它基本上允许我根据在jar中找到的图像的名称获取Drawables
构造器从zip文件中接收zipFileModule和文件名列表(任何以.png结尾的文件)
进行的研究:
我使用了以下方法:
起初,我创建的图像大小为每种密度,但现在我只有一组图像图标大小为96x96
如果屏幕密度小于xhdpi,我将加载96x96图像的较小采样尺寸-对于ldpi为36x36,对于mdpi为48x48,对于hdpi为72x72。否则我只返回96x96图像。查看方法CalculatesSampleSize和bytesToDrawable
我认为通过代码更容易理解这个概念:下面是ModularImageLoader
代码:
问题:
下图显示了4个正在运行的模拟器,这些是它们的规范以及我如何在eclipse AVD中设置它们:
LDPI:密度120,皮肤QVGA
MDPI:密度160,皮肤HVGA
HDPI:密度240,皮肤WVGA800
XHDPI:密度320,外皮800x1280
图像显示问题:
问题:
基于XHDPI窗口中的代码,为什么联系人图像这么小?除了从主应用程序加载外,新闻图像也是96x96,因此它位于res>XHDPI下。
问题是,我认为MDPI屏幕和HDPI屏幕的加载很好,但其他屏幕的加载很奇怪。有什么想法吗?您应该使用BitmapDrawableResources res,位图位图构造器,它将确保drawable的目标密度设置正确,您使用的构造器不推荐使用
如果你看你的LDPI屏幕,联系人的图像实际上有点太小,HDPI屏幕也有点太小。只有在MDPI屏幕上,它才看起来完全正确,因为默认的目标密度是MDPI 您应该使用BitmapDrawableResources res,位图位图构造函数,它将确保可绘制文件的目标密度设置正确,您使用的构造函数已被弃用
如果你看你的LDPI屏幕,联系人的图像实际上有点太小,HDPI屏幕也有点太小。只有在MDPI屏幕上,它才看起来完全正确,因为默认的目标密度是MDPI 您可以使用dp创建所需的高度和宽度,然后将其转换为px,以获得缩放图像的正确大小 假设您希望您的图像为32x32dp
int reqWidth = dpToPx(context, 32);
int reqHeight = dpToPx(context, 32);
public static int dpToPx(Context context, int dp) {
return (int) (dp * (context.getResources().getDisplayMetrics().densityDpi / 160f) + 0.5f);
}
您可以使用dp创建所需的高度和宽度,然后将其转换为px以获得缩放图像的正确大小 假设您希望您的图像为32x32dp
int reqWidth = dpToPx(context, 32);
int reqHeight = dpToPx(context, 32);
public static int dpToPx(Context context, int dp) {
return (int) (dp * (context.getResources().getDisplayMetrics().densityDpi / 160f) + 0.5f);
}
如果使用BitmapFactory.Options提供密度信息,则BitmapFactory可以为您缩放图像。如果这样做,您应该能够删除ModularImageLoader中的自定义缩放代码 指定inDensity和inTargetDensity-如下所示:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDensity = DisplayMetrics.DENSITY_MEDIUM;
options.inTargetDensity = activityRef.getResources().getDisplayMetrics().densityDpi;
options.inScaled = true;
return BitmapFactory.decodeStream(openByteStream(), null, options);
BitmapFactory.decodeByteArray中显然存在忽略某些缩放选项的错误,因此您可能需要将字节数组包装在ByteArrayInputStream中,并使用BitmapFactory.decodeStream,如上图所示。如果使用BitmapFactory.options提供密度信息,BitmapFactory可以为您缩放图像。如果这样做,您应该能够删除ModularImageLoader中的自定义缩放代码 指定inDensity和inTargetDensity-如下所示:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDensity = DisplayMetrics.DENSITY_MEDIUM;
options.inTargetDensity = activityRef.getResources().getDisplayMetrics().densityDpi;
options.inScaled = true;
return BitmapFactory.decodeStream(openByteStream(), null, options);
BitmapFactory.decodeByteArray中显然存在忽略某些缩放选项的错误,因此您可能需要将字节数组包装在ByteArrayInputStream中,并使用BitmapFactory.decodeStream,如上图所示。请参见。ldpi-36x36
mdpi-48x48
hdpi-72x72
xhdpi-96x96
如果这些都是彼此的纯倍数,那就太好了,因为位图工厂以整数处理样本大小,因此样本大小需要是一个整数,没有尾随小数才能完全准确
解决方案:
在开始采样之前,每种屏幕类型有一个图像,如果该图像处于按下状态,则会有两个单独的图像
因此,对于一个图像-我在应用程序中实际需要4,如果该图像已按下状态-一个图像将需要8 ima
盖斯
我的主要目标是减少图像的数量,这样我就不会过载位图堆分配并可能抛出内存不足异常,我已经看到这个异常为我抛出,当我的位图大小完全合理时,我相信这与堆上的图像数量以及它们各自的图像大小有关。如果我错了,请纠正我。。当然,我想减少我的模块大小
所以我决定:
每个图像有2个图像-一个大小为72,一个大小为96-这样我就有了xhdpi和hdpi密度屏幕所需的图标,我可以在需要时使用ldpi和mdpi
72/2=36
96/2=48
这样的话,每个图像只有2个图像,最坏的情况是,如果该图像已按下状态,我将有4个图像。
这将图像库的大小减少了近50%,并使我的模块更小。我注意到模块大小从525KB变为329 kb左右
这确实是我的目标
谢谢大家的帮助!如果有任何问题,请随时发表评论,我会尽快回复您。ldpi-36x36
mdpi-48x48
hdpi-72x72
xhdpi-96x96
如果这些都是彼此的纯倍数,那就太好了,因为位图工厂以整数处理样本大小,因此样本大小需要是一个整数,没有尾随小数才能完全准确
解决方案:
在开始采样之前,每种屏幕类型有一个图像,如果该图像处于按下状态,则会有两个单独的图像
因此,对于一个图像-我在应用程序中实际需要4个,如果该图像已按下状态-一个图像将需要8个图像
我的主要目标是减少图像的数量,这样我就不会过载位图堆分配并可能抛出内存不足异常,我已经看到这个异常为我抛出,当我的位图大小完全合理时,我相信这与堆上的图像数量以及它们各自的图像大小有关。如果我错了,请纠正我。。当然,我想减少我的模块大小
所以我决定:
每个图像有2个图像-一个大小为72,一个大小为96-这样我就有了xhdpi和hdpi密度屏幕所需的图标,我可以在需要时使用ldpi和mdpi
72/2=36
96/2=48
这样的话,每个图像只有2个图像,最坏的情况是,如果该图像已按下状态,我将有4个图像。
这将图像库的大小减少了近50%,并使我的模块更小。我注意到模块大小从525KB变为329 kb左右
这确实是我的目标
谢谢大家的帮助!如果任何人有任何问题,请随时留下评论,我会尽快回复您。我很喜欢这样做,但我更愿意使用“位图工厂采样”选项。我将在将来的某个时候在我的应用程序中尝试这一点,因为我肯定可以将其用于大徽标,我希望适合任何任意值的特定大小。我确实喜欢这一点,但我宁愿使用位图工厂选项的采样。我将在将来的某个时候在我的应用程序中尝试这一点,因为我肯定可以将其用于大型徽标,我希望适合任何任意值的特定大小。你是对的,我已将其更改以反映较新的构造函数。好主意。你说得对,我修改了它以反映新的构造函数。好主意。你能解释一下inDensity到底是做什么的吗?我可以告诉你将其设置为中等,然后将目标密度设置为手机返回的屏幕密度。你能解释inDensity的确切功能吗?我可以告诉你,你把它设置为中等,然后你把目标密度设置为手机返回的屏幕密度。天哪。我在这个问题上花了几个小时,所做的一切就是改变这个:使用BitmapDrawableResources res,位图位图而不是BitmapDrawableBitmap位图:谢谢谢谢谢谢!!!!天哪。我在这个问题上花了几个小时,所做的一切就是改变这个:使用BitmapDrawableResources res,位图位图而不是BitmapDrawableBitmap位图:谢谢谢谢谢谢!!!!