如何在Android上高效地绘制放大的像素艺术?

4
我正在制作一个包含大量像素艺术的游戏。我的游戏中,标准按钮大约是12x12个像素并缩放了5倍用于显示。所有字符也会根据屏幕的大小放大两倍。问题是,如果我将所有这些图像存储为放大的位图,Android会报内存不足的错误。如果我每次绘制时都尝试进行缩放,游戏运行非常缓慢。

因此,我编写了自己的PixelArtBitmap类。它可以生成高质量的图像,并且占用极少的内存,但效率很低,导致我的fps下降很多。但它仍然比每次绘制时缩放位图要快。以下是该类:

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

class PixelArtBitmap{
    private int[][] pixels = null;
    private boolean[][] visible = null;

    private float width = 0;
    private float height = 0;

    private float drawWidth = 0;
    private float drawHeight = 0;

    private int pixelsX = 0;
    private int pixelsY = 0;

    private static Paint boxPaint = new Paint();

    public PixelArtBitmap(Bitmap bitmap, float scale){
        boxPaint.setStrokeWidth(0);

        pixels = new int[bitmap.getWidth()][bitmap.getHeight()];
        visible = new boolean[bitmap.getWidth()][bitmap.getHeight()];

        pixelsX = bitmap.getWidth();
        pixelsY = bitmap.getHeight();

        //Utility is an another class of mine, providing information about the device
        drawWidth = scale * Utility.getScaleWidth();
        drawHeight = scale * Utility.getScaleHeight();

        width = pixelsX * drawWidth;
        height = pixelsY * drawHeight;

        for(int x = 0 ; x < bitmap.getWidth() ; x++){
            for(int y = 0 ; y < bitmap.getHeight() ; y++){
                pixels[x][y] = bitmap.getPixel(x,y);

                if(Color.alpha(pixels[x][y]) == 0) visible[x][y] = false;
                else visible[x][y] = true;
            }
        }

        bitmap.recycle();
        bitmap = null;
    }

    public void draw(float x, float y, Canvas canvas){
        for(int drawY = 0 ; drawY < pixelsY ; drawY++){
            for(int drawX = 0 ; drawX < pixelsX ; drawX++){
                if(visible[drawX][drawY]){
                    boxPaint.setColor(pixels[drawX][drawY]);
                    canvas.drawRect(x + drawWidth * drawX, y + drawHeight * drawY,
                            x + drawWidth * (drawX + 1), y + drawHeight * (drawY + 1), boxPaint);
                }
            }
        }
    }
}

那么,我该如何使这个类更快,或者有没有完全不同的方法来正确地完成这个任务?

你是否在使用“Canvas”在屏幕上绘制这些位图?如果是的话,考虑尝试在运行时使用“Canvas.drawBitmap(Bitmap,null,dstRect,Paint)”来放大较小的位图。我相当确定在“Paint”中有一个标志可以启用最近邻缩放,如果这不是默认值的话。 - harism
谢谢你的建议,我会尽快尝试。 - Finnboy11
看起来很不错!如果你愿意,你可以把它作为一个解决方案添加进去,我会接受的。 - Finnboy11
1个回答

3

不必创建一个新的更大的位图,您也可以直接将较小尺寸的位图绘制到新尺寸中,方法如下:

Canvas.drawBitmap(Bitmap, null, dstRect, Paint);

这个方法应该将原始的位图重新调整大小为dstRect,我相当确定有一个设置可以选择最近邻过滤。这应该使您能够直接绘制较小的图像到所需的尺寸,同时保留像素艺术外观。


1
paint.setAntiAlias(false); 和 pixelPaint.setFilterBitmap(false); 对我来说都有效。再次感谢! - Finnboy11

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