在Android中如何以最优方式调整位图大小?

4
假设我有一个六边形:

hexagon

如果我将其调整大小以在包含六边形网格的应用程序中使用:
// ...
bgPaint = new Paint();
bgPaint.setAntiAlias(true);
bgPaint.setDither(true);

// ...
Bitmap coloredBackground = BitmapFactory.decodeResource(getResources(), R.drawable.bg);

// ...
canvas.drawBitmap(coloredBackground, null, getAsRect(), bgPaint);

我得到了这个:

六边形

getAsRect() 返回一个Rect对象,我用它来绘制。我想要实现的是去掉边缘的透明像素。我认为我做错了什么,但我还没有找到原因。你有任何想法如何解决这个问题吗?

我尝试过使用抖动和反锯齿,但没有改变。

4个回答

7

三个建议:

1

尝试这样做:当您解码资源时,通过将BitmapFactory.Options.inScaled设置为false来关闭系统的缩放:

Options options = new BitmapFactory.Options();
options.inScaled = false;
Bitmap source = BitmapFactory.decodeResource(context.getResources(), R.drawable.bg, options);
inScaled标志应该关闭,如果你需要非缩放版本的位图。
然后使用Bitmap.createScaledBitmap(...)缩放你的位图。
另一个可能的原因是你的瓷砖的对角线黑线包含不同灰度的颜色。
这是你的瓷砖的近距离图像: enter image description here 它在调整大小之前进行了抗锯齿处理。任何不完全黑色的像素都可能会在调整大小后显示为较浅的颜色。你可以将线条改为完全黑色(0xFF000000),并只在调整大小后进行抗锯齿处理。
解决此问题的另一种方法是设计你的瓷砖如下所示,避免在彼此相邻的两个反锯齿对角线旁绘制。 enter image description here

BitmapFactory 似乎没有 createScaledBitmap 方法。我正在使用 API 级别 9。你是不是指的是 Bitmap.createScaledBitmap - Adam Arold
你的解决方案非常好(方法1和2结合使用)!3在这里不适用。它还加快了程序的速度,因为缩放只发生一次。 - Adam Arold
啊,好主意。如果你有兴趣,也可以使用绘制算法来绘制六边形图案,而不是使用可绘制对象。这是一个C#的例子:http://www.codeproject.com/Articles/14948/Hexagonal-grid-for-games-and-other-projects-Part-1 - Gunnar Karlsson
是的,我知道。事实上,我只使用可绘制对象是因为我需要一些图形,但我也能够在没有图形的情况下绘制那些六边形。 - Adam Arold

1
为什么不使用这个呢?
Bitmap.createScaledBitmap(decodedBitmap, targetWidth, targetHeight, true);

1
您可以尝试使用hqx调整大小算法:

或者,您可以在更大的表面上绘制,并一起缩放该表面。


0
我正在按照以下方式调整图像大小:
    String url = ""; //replace with path to your image  
    int imageDimension = 48; // replace with required image dimension

    //decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(new FileInputStream(url), null, o);

    //Find the correct scale value. It should be the power of 2.
    final int REQUIRED_SIZE = imageDimension;
    int width_tmp = o.outWidth, height_tmp = o.outHeight;
    int scale = 1;
    while(true){
        if(width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
            break;
        width_tmp /= 2;
        height_tmp /= 2;
        scale *= 2;
    }

    //decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    Drawable drawable =  new BitmapDrawable(context.getResources(),    BitmapFactory.decodeStream(new FileInputStream(url), null, o2));

我不确定你在这里做什么,能否解释一下代码?你是在缩小超过“REQUIRED_SIZE”吗? - Sebastian Mach
是的,这段代码将图像调整为新尺寸(imageDimension * imageDimension)。 - Veaceslav Gaidarji
我觉得你没有理解我的关注点。 - Sebastian Mach

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