缩小 Android 位图总是导致锯齿状边缘
Downsizing Android Bitmap always results in jagged edges
当我在 Android 设备上缩小图像时,无论我尝试什么,我都看到非常难看的伪影/锯齿状边缘。我浏览了在 Whosebug 和博客上找到的几种可能的解决方案,似乎一切都给我类似的结果。
原始图像 (4096 x 4096):
缩放图像 (214 x 214)(注意锯齿状边缘):
我尝试过的:
- 使用
Paint
抗锯齿并启用过滤功能将图像绘制到 Canvas
BitmapFactory.decode
的多种变体
bitmap.scale()
- Compressor - Android 图像缩放库
以上所有试验都产生了几乎完全相同的结果。这是一个很常见的问题,我肯定忽略了某些事情,或者没有正确地做某事。
如果我使用基于网络的图像缩放器,结果如下:
它应该是什么样子:
如何才能得到与上图相同的结果?
试用图像中缺乏平滑度表明缺少一些抗锯齿功能。
相对快速的搜索表明 Sub-pixel antialiasing rules 可能会变得复杂。
接下来是找出“基于网络的图像缩放器”用于生成试用图像的工具。
十分之九(或更多)的网站将使用 FOSS 软件,这将导致 ImageMagick
通过 ImageMagick 使用如下命令快速 运行 源图像:
convert SO_source_image.png -resize 5% SO_result.png
这张相似但不准确(205x205 像素)图像的结果:
此时您可以深入了解 ImageMagick 使用的算法(请参阅 command line options for the variety of methods) or see if you can get a similar result with an existing port like: cherryleafroad/Android-ImageMagick7 or paulasiimwe/Android-ImageMagick
有一种棘手的方法可以(设法)仅使用标准 API 实现该目标。只是避免立即缩小位图。
Bitmap bitmap = BitmapFactory.decodeStream(stream);
:
Matrix m = new Matrix();
m.setScale(0.5F, 0.5F);
while (bitmap.getWidth() > 256)
{
Bitmap bitmap_half = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
bitmap.recycle();
bitmap = bitmap_half;
}
imageView.setImageBitmap(bitmap);
结果:
这是如何工作的:
由于滤波器是短程的(主要设计用于放大,例如双线性或双三次),在一般情况下它对于缩小(=离散重采样)是无用的。
然而,它确实参考相邻像素来计算新的像素颜色。因此,通过避免过于稀疏的重采样,可以使其用作按比例缩小的平滑滤波器。也许。
当我在 Android 设备上缩小图像时,无论我尝试什么,我都看到非常难看的伪影/锯齿状边缘。我浏览了在 Whosebug 和博客上找到的几种可能的解决方案,似乎一切都给我类似的结果。
原始图像 (4096 x 4096):
缩放图像 (214 x 214)(注意锯齿状边缘):
我尝试过的:
- 使用
Paint
抗锯齿并启用过滤功能将图像绘制到Canvas
BitmapFactory.decode
的多种变体
bitmap.scale()
- Compressor - Android 图像缩放库
以上所有试验都产生了几乎完全相同的结果。这是一个很常见的问题,我肯定忽略了某些事情,或者没有正确地做某事。
如果我使用基于网络的图像缩放器,结果如下:
它应该是什么样子:
如何才能得到与上图相同的结果?
试用图像中缺乏平滑度表明缺少一些抗锯齿功能。
相对快速的搜索表明 Sub-pixel antialiasing rules 可能会变得复杂。
接下来是找出“基于网络的图像缩放器”用于生成试用图像的工具。
十分之九(或更多)的网站将使用 FOSS 软件,这将导致 ImageMagick
通过 ImageMagick 使用如下命令快速 运行 源图像:
convert SO_source_image.png -resize 5% SO_result.png
这张相似但不准确(205x205 像素)图像的结果:
此时您可以深入了解 ImageMagick 使用的算法(请参阅 command line options for the variety of methods) or see if you can get a similar result with an existing port like: cherryleafroad/Android-ImageMagick7 or paulasiimwe/Android-ImageMagick
有一种棘手的方法可以(设法)仅使用标准 API 实现该目标。只是避免立即缩小位图。
Bitmap bitmap = BitmapFactory.decodeStream(stream);
:
Matrix m = new Matrix();
m.setScale(0.5F, 0.5F);
while (bitmap.getWidth() > 256)
{
Bitmap bitmap_half = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
bitmap.recycle();
bitmap = bitmap_half;
}
imageView.setImageBitmap(bitmap);
结果:
这是如何工作的:
由于滤波器是短程的(主要设计用于放大,例如双线性或双三次),在一般情况下它对于缩小(=离散重采样)是无用的。 然而,它确实参考相邻像素来计算新的像素颜色。因此,通过避免过于稀疏的重采样,可以使其用作按比例缩小的平滑滤波器。也许。