缩小 Android 位图总是导致锯齿状边缘

问题描述 投票:0回答:3

无论我尝试什么,当我在 Android 设备上缩小图像时,我都看到非常难看的伪影/锯齿状边缘。我浏览了在 StackOverflow 和博客上找到的几种可能的解决方案,一切似乎都给我类似的结果。

原始图像(4096 x 4096):

缩放图像(214 x 214)(注意锯齿状边缘):

我尝试过的:

  1. 使用具有抗锯齿和过滤功能的
    Canvas
    将图像绘制成
    Paint
  2. 多种变体
    BitmapFactory.decode
  3. bitmap.scale()
  4. Compressor - Android 图像缩放库

以上所有试验都产生了几乎完全相同的结果。这是一个如此普遍的问题,我肯定忽略了某些事情,或者没有正确地做某事。

如果我使用基于网络的图像缩放器,结果如下: 它应该是什么样子:

我怎样才能得到与上图相同的结果?

android image-scaling
3个回答
2
投票

试用图像中缺乏平滑度表明缺少一些抗锯齿功能。

一个相对快速的搜索表明亚像素抗锯齿规则会变得复杂。

接下来要弄清楚“基于网络的图像缩放器”用于生成试用图像的工具。

十分之九(或更多)的网站将使用 FOSS 软件,这将导致 ImageMagick

使用如下命令通过 ImageMagick 快速运行源图像:

convert SO_source_image.png -resize 5% SO_result.png

这个相似但不精确(205x205 像素)图像的结果:

此时您可以深入研究 ImageMagick 使用的算法(请参阅 命令行选项以了解各种方法)或者看看您是否可以使用现有端口获得类似的结果,例如:cherryleafroad/Android-ImageMagick7或者 paulasiimwe/Android-ImageMagick


1
投票

有一种棘手的方法(设法)仅使用标准 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);

结果:

这是如何运作的:

由于过滤器是短程的(主要设计用于放大,例如双线性或双三次),在一般情况下它对于缩小(=离散重采样)是无用的。 然而,它确实参考相邻像素来计算新的像素颜色。因此,通过避免过于稀疏的重采样,可以使其用作按比例缩小的平滑滤波器。也许。


0
投票

BitmapCompat.createScaledBitmap() 将以更高的质量缩小。该函数的文档指出:“该算法用于在需要高质量时按大比例缩小比例”

© www.soinside.com 2019 - 2024. All rights reserved.