2

我正在尝试在我的 android 应用程序中将可变位图中的像素区域设置为不同的颜色。不幸的是,我无法让 setPixels() 正常工作。我不断收到 ArrayOutOfBoundsExceptions。我认为这可能与步幅有关,但我真的不确定。这是我仍然不明白的唯一参数。我在 setPixels(不是 setPixel)上看到的唯一其他帖子是:drawBitmap() 和 setPixels():步幅是多少?它没有帮助我。我尝试将步幅设置为 0,作为位图的宽度,作为位图的宽度——我试图绘制的区域,它仍然崩溃。这是我的代码:

public void updateBitmap(byte[] buf, int offset, int x, int y, int width, int height) {
    // transform byte[] to int[]
    IntBuffer intBuf = ByteBuffer.wrap(buf).asIntBuffer();
    int[] intarray = new int[intBuf.remaining()];
    intBuf.get(intarray);                                       

    int stride = ??????
    screenBitmap.setPixels(intarray, offset, stride, x, y, width, height); // crash here

我的位图是可变的,所以我知道这不是问题。我也确定我的字节数组正在正确转换为整数数组。但是我不断收到 ArrayOutOfBoundsExceptions ,我不明白为什么。请帮我解决这个问题

编辑 - 这是我构造假输入的方式:

int width = 1300;
int height = 700;
byte[] buf = new byte[width * height * 4 * 4]; // adding another * 4 here seems to work... why?     
for (int i = 0; i < width * height * 4 * 4; i+=4) {
    buf[i] = (byte)255;
    buf[i + 1] = 3;
    buf[i + 2] = (byte)255;
    buf[i + 3] = 3;         
}
//(byte[] buf, int offset, int x, int y, int width, int height)  - for reference        
siv.updateBitmap(buf, 0, 0, 0, width, height);

所以宽度和高度是正确的整数数量(至少应该是)。

EDIT2 - 这是screenBitmap的原始创建代码:

public Bitmap createABitmap() {
int w = 1366;
int h = 766;

byte[] buf = new byte[h * w * 4];

for (int i = 0; i < h * w * 4;i+=4) {
        buf[i] = (byte)255;
    buf[i+1] = (byte)255;
    buf[i+2] = 0;
    buf[i+3] = 0;
}

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

IntBuffer intBuf = ByteBuffer.wrap(buf).asIntBuffer();  
int[] intarray = new int[intBuf.remaining()];
intBuf.get(intarray);                                           

Bitmap bmp = Bitmap.createBitmap(metrics, w, h, itmap.Config.valueOf("ARGB_8888"));
bmp.setPixels(intarray, 0, w, 0, 0, w, h);
return bmp;
}

它似乎在这种情况下工作,不知道有什么区别

4

3 回答 3

1

可能应该是:

screenBitmap.setPixels(intarray, 0, width / 4, x, y, width / 4, height);

因为您已将字节转换为 int。您的错误是 ArrayOutOfBoundsExceptions。检查大小是否intBuf.remaining() = width * height / 4

于 2013-09-26T05:40:25.397 回答
1

简短 我认为,stride是以像素为单位的图像宽度。

我从文档中得到的,算法应该像这样工作:

public void setPixels (int[] pixels, 
            int offset, 
            int stride, 
            int x, 
            int y, 
            int width, 
            int height)
    for (int rowIndex = 0; rowIndex < height; rowIndex++) {
        int rowStart = offset + stride * rowIndex; // row position in pixels
        int bitmapY = y + rowIndex; // y position in the bitmap
        for (int columnIndex = 0; columnIndex < width; columnIndex++) {
            int bitmapX = x + columnIndex; // x position in the bitmap
            int pixelsIndex = rowStart + columnIndex; // position in pixels
            setPixel(bitmapX, bitmapY, pixels[pixelsIndex]);

        }
    }
}

至少这是我对这些参数所做的,因为它允许您将一个pixels作为源并剪切出不同大小的不同图像。如果我错了,请随时更正算法。

因此,假设您有一个带有pixelsWidthpixelsHeightin的图像pixels。然后你想复制一个部分 at pixelsXand pixelsYwith widthandheight到一个bitmapat 位置bitmapXand bitmapY。这应该是调用:

bitmap.setPixels(
    pixelsWidth * pixelsY + pixelsX, // offset
    pixelsWidth, // stride
    bitmapX, // x
    bitmapY, // y
    width,
    height)
于 2020-02-27T11:07:36.917 回答
0

如果您尝试在位图上绘图,最好的方法是放弃此方法并改用画布:

Canvas canvas = new Canvas(screenBitmap);

然后,您可以绘制特定点(如果要绘制像素)或其他形状,如矩形、圆形等:

canvas.drawPoint(x, y, paint);

ETC

希望这可以帮助。

于 2013-09-26T05:33:11.960 回答