Android:在运行时调整大小的图像质量

13

我想使用drawBitmap()方法显示图片,但在此之前我希望根据屏幕尺寸调整图片大小。我在结果图像的质量上遇到了问题。您可以在下面看到截图和测试代码。如何以良好的质量在运行时调整图像大小?

感谢您提供的解决方案。

原始图片: alt text http://dl.dropbox.com/u/709109/gradient.png

设备上的结果截图: alt text http://dl.dropbox.com/u/709109/device.png

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;

import java.io.IOException;
import java.io.InputStream;

public class MyActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        LinearLayout container = (LinearLayout) findViewById(R.id.container);
        container.addView(new View(this) {
            @Override
            protected void onDraw(Canvas canvas) {
                Bitmap unscaledBitmap;
                try {
                    InputStream in = getAssets().open("images/gradient.png");
                    unscaledBitmap = BitmapFactory.decodeStream(in);
                    in.close();
                    canvas.drawBitmap(unscaledBitmap, null, new Rect(0, 0, 320, 480), null);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
6个回答

15

不要在绘制时调整大小(这将非常昂贵),尝试在离屏位图中调整大小,并确保该位图为32位(ARGB888)。


据我所知,Android只有在使用***BitmapFactory.Options :: inSampleSize-> BitmapFactory.decodeResource()***时才应用良好的缩小算法(而不是最近邻),但这仅允许缩小到原始大小的整数倍。在Android中,是否有一种方法可以使用比最近邻算法更好的东西来缩小到我需要的确切分辨率(每次调用createScaledBitmap(),createBitmap + matrix等都会使用最近邻算法)? - goRGon

10
请参考下面Romain的答案
我想删除这个答案,但由于标记为已接受,所以我无法删除。
请注意,Android(当这个答案最初发布时,没有明确请求32位颜色)仅支持16位颜色,因此有时可能会出现不需要的伪像。
您还可以尝试使用抖动选项告诉Android自动应用抖动,虽然不完美,但可以帮助使事物看起来更好一些。

1
谢谢,这个回答很有帮助!但是我没有声望来投票。 - shinydev
现在我正在使用“565抖动Photoshop插件”来准备我的图形。因为抖动是一项高成本操作,而且它不能与decodeStream和drawBitmap方法一起使用。 - shinydev
1
Android可以很好地处理32位。只需确保您的位图和窗口都使用ARGB8888格式即可。 - Romain Guy
@RomainGuy 这一直都是这样吗?只是好奇,不知道两年前我写这个的时候是否也是如此.. :) 无论如何,我会删除我的答案,选择你的答案,显然两年前我也给了它点赞! - Christopher Orr
3
两年前这是正确的,只需要通过应用程序请求即可。32位现在是默认设置。 - Romain Guy
@Roces 不用担心,我已经为你做了这件事。 - Akshat Agarwal

2

BitmapFactory.Options 中的“质量设置”是什么?我找不到任何相关信息,文档中也没有提到“质量”一词。 - William Denniss
有http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inPreferQualityOverSpeed,但文档说它只适用于JPEG解码,而您的文件是PNG。 - typo.pl

1

在旧平台上(API级别<12),实现createScaledBitmap(..)方法会在尝试缩放没有实际alpha值的ARGB_8888位图(即每个像素的alpha = 255)时导致问题,因为它们的hasAlpha标志设置为false。在这种情况下,缩放的位图会自动转换为RGB_565格式。

因此,自API级别12以来,Bitmap类中有一个方法可用。

setHasAlpha(boolean value);

使用createScaledBitmap(..)时有助于防止转换。

在API级别> 3上有一种方法可以使用完全相同的方法。它已经存在很长时间,只是隐藏起来了。包括源代码在内的所有必要步骤都在这里描述:

https://dev59.com/XG445IYBdhLWcg3wgqrT#12202069

希望这能有所帮助。

0

-1
此外,如果您的调整大小函数不尊重图像的纵横比,则会影响质量。您可以在网上找到一些调整大小算法,例如看看这个

不,这两张图片具有相同的比例。原始图片:600x900 比例1.5 新图片尺寸:320x480 比例1.5 - shinydev
在您提供的链接中没有找到任何调整大小算法,只有关于正确比例值计算的讨论... - goRGon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接