在Android培训文档中,article有效地加载大型位图,讨论计算inSampleSize
以在加载图像时对其进行下采样。这是共享的代码示例。
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;
}
对我来说没有意义的是在这里使用halfHeight
和halfWidth
。让我们来看一个真实世界的例子,这样我就可以表明我的意思了。
我想将用户的照片加载到OpenGL纹理中。我已经查询过发现GL_MAX_TEXTURE_SIZE
是4096.用户选择了4320x2432的照片,所以我需要将其缩小一点。
我调用了docs中提供的静态帮助方法:
options.inSampleSize = BitmapUtils.calculateInSampleSize(options, maxTextureSize, maxTextureSize);
单步执行此代码,halfHeight
将为1216,halfWidth
将为2160,如果该值除以inSampleSize仍然大于请求的维度,则inSampleSize将仅为1以外。
当我运行此设置时,inSampleSize
设置为1,它根本不会缩小图像,并且OpenGL会因为大于GL_MAX_TEXTURE_SIZE
而抛出拟合。
我的问题是为什么我们在这里除以二?我不在乎我的一半图像是否符合要求的尺寸,我希望整个图像都合适。如果inSampleSize
和(halfHeight / inSampleSize) > reqHeight
一直跟(halfWidth / inSampleSize) > reqWidth
碰撞会不会更有意义?
答案 0 :(得分:2)
这是我对这种方法意图的误解。我以为我们正在寻找一个inSampleSize来解码一个Bitmap以使内部符合要求的尺寸。我现在看到该方法旨在返回一个值来解码一个位图,该位图尽可能接近但不小于所请求的大小。
答案 1 :(得分:1)
奇怪的是,这个问题回答了我的意思。我对方法感到困惑:
// 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;
}
这不会使高度和宽度都大于reqHeight和reqWidth。一旦其中一个小于相关值,循环就会结束。但是,因为该方法使用halfHeight和halfWeight,它有点像在超越标记后退一步......或者测量前面的步骤,而不是...
无论如何,我正在考虑手头的问题并最终得到以下结论:
boolean condition = (height / 2 / inSampleSize) > reqHeight
&& (width / 2 / inSampleSize) > reqWidth;
for (; condition; inSampleSize *= 2) {
}
这样使用for循环是不合适的吗?也许简单地使用会更清楚:
while ((height / 2 / inSampleSize) > reqHeight
&& (width / 2 / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
无论如何,我会尝试更好地回答你的实际问题。我认为这种方法旨在最大限度地减少内存使用,而不是提供具有精确所需大小的位图。缩小图像时,因子2是一个相当大的跳跃;你可能最终得到的位图只有你想要的尺寸的一半,然后必须扩大规模。我只是学习如何使用图像并且完全在猜测,但是这看起来比缩小几乎是所需尺寸的两倍的图像更糟糕吗?