我试图在我的Android应用程序中将可变位图中的像素区域设置为不同的颜色。不幸的是我无法让setPixels()正常工作。我经常得到ArrayOutOfBoundsExceptions。我认为这可能与步幅有关,但我真的不确定。这是我仍然不理解的唯一参数。我在setPixels(而不是setPixel)上看过的唯一一篇文章就在这里:drawBitmap() and setPixels(): what's the stride?它并没有帮助我。我尝试将步幅设置为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;
}
在这种情况下似乎有效,不确定区别是什么
答案 0 :(得分:1)
可能应该是:
screenBitmap.setPixels(intarray, 0, width / 4, x, y, width / 4, height);
因为您已将byte转换为int。您的错误是ArrayOutOfBoundsExceptions。检查尺寸intBuf.remaining() = width * height / 4
。
答案 1 :(得分:0)
如果您正在尝试绘制位图,最好的方法是放弃此方法并使用画布代替:
Canvas canvas = new Canvas(screenBitmap);
然后您可以绘制特定点(如果您想绘制像素),或其他形状,如矩形,圆形等:
canvas.drawPoint(x, y, paint);
等
希望这有帮助。
答案 2 :(得分:0)
短
我认为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
作为源并剪切出不同大小的不同图像。
如果我错了,请随时纠正算法。
因此,假设您在pixelsWidth
中有一个带有pixelsHeight
和pixels
的图像。
然后,您想将pixelsX
和pixelsY
的{{1}}和width
中的节复制到位置height
和{{1}处的bitmap
}。
这应该是呼叫:
bitmapX