学习Graphics中遇到位图(Bitmap)中getPixels()方法,对该方法的用法大体理解,但对其中的stride参数却不明白具体的用法以及用意,现记述过程如下:
public void getPixels (int[] pixels, int offset, int stride, int x, int y, int width, int height)
Returns in pixels[] a copy of the data in the bitmap. Each value is a packed int representing a Color
. The stride parameter allows the caller to allow for gaps in the returned pixels array between rows. For normal packed results, just pass width for the stride value.
The array to receive the bitmap's colors |
The first index to write into pixels[] |
The number of entries in pixels[] to skip between rows (must be >= bitmap's width). Can be negative. |
The x coordinate of the first pixel to read from the bitmap |
The y coordinate of the first pixel to read from the bitmap |
The number of pixels to read from each row |
The number of rows to read |
if x, y, width, height exceed the bounds of the bitmap, or if abs(stride) < width. |
if the pixels array is too small to receive the specified number of pixels. |
public void getPixels (int[] pixels, int offset, int stride, int x, int y, int width, int height)
把位图的数据拷贝到pixels[]中。每一个都由一个表示颜色值的int值来表示。幅度参数(stride)表明调用者允许的像素数组行间距。对通常的填充结果,只要传递宽度值给幅度参数。
参数
pixels接收位图颜色值的数组
offset写入到pixels[]中的第一个像素索引值
stride pixels[]中的行间距个数值(必须大于等于位图宽度)。可以为负数
x 从位图中读取的第一个像素的x坐标值。
y 从位图中读取的第一个像素的y坐标值
width 从每一行中读取的像素宽度
height 读取的行数
异常
IllegalArgumentExcepiton 如果x,y,width,height越界或stride的绝对值小于位图宽度时将被抛出。
ArrayIndexOutOfBoundsException如果像素数组太小而无法接收指定书目的像素值时将被抛出。
2 Stride is number of bytes used for storing one image row.
Most of the images are 4 byte aligned.
图像大小为100*100,想截取图片右上1/4图像(图上黄色部分)修改程序部分代码为:
int[] pixels = new int[w*h]; mBitmap2.getPixels(pixels, 0, w, 50, 0, w/2, h/2); mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h, Bitmap.Config.ARGB_8888); mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h, Bitmap.Config.ARGB_4444); String txt = String.valueOf(pixels[10]); Log.i("myBitmapDecode", "w = " + w + "; h = " + h); Log.i("myBitmapDecode", "pixels[0] = " + pixels[0] + "; pixels[1] = " + pixels[1] + "; pixels[10] = " + pixels[10]); Log.i("myBitmapDecode", "pixels[w] = " + pixels[w] + "; pixels[h] = " + pixels[h] + "; pixels[w*h-1] = " + pixels[w*h-1]);运行结果:
我们看到右边两副ARGB_8888,ARGB_4444图像隐约只在左上角显示原图右上的1/4黄色部分,其余部分为背景色白色,那么问题又来了,此时ARGB_8888,ARGB_4444图像大小为多少?还是原图的大小(100*100)吗,或者是(50*50)了,不然背景色为何是画布的背景色呢(白色)?那么把 pixels[100*100]数组设初始值看下情况(通过Log.i()我查到了pixels中存储的像素值为百万左右的负整数(-16777216),所以这里胡乱取个数-2578654做为初始值,颜色不太好,请见谅),修改后代码如下:
int[] pixels = new int[w*h]; for(int i=0; i<w*h; i++){ pixels[i] = -2578654; } mBitmap2.getPixels(pixels, 0, w, 50, 0, w/2, h/2); mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h, Bitmap.Config.ARGB_8888); mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h, Bitmap.Config.ARGB_4444); String txt = String.valueOf(pixels[10]); Log.i("myBitmapDecode", "w = " + w + "; h = " + h); Log.i("myBitmapDecode", "pixels[0] = " + pixels[0] + "; pixels[1] = " + pixels[1] + "; pixels[10] = " + pixels[10]); Log.i("myBitmapDecode", "pixels[w] = " + pixels[w] + "; pixels[h] = " + pixels[h] + "; pixels[w*h-1] = " + pixels[w*h-1]);运行结果:
offset = x + y*w ,本例代码如下:
int[] pixels = new int[w*h]; for(int i=0; i<w*h; i++){ pixels[i] = -2578654; } mBitmap2.getPixels(pixels, 50, w, 50, 0, w/2, h/2; mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h, Bitmap.Config.ARGB_8888); mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h, Bitmap.Config.ARGB_4444); String txt = String.valueOf(pixels[10]); Log.i("myBitmapDecode", "w = " + w + "; h = " + h); Log.i("myBitmapDecode", "pixels[0] = " + pixels[0] + "; pixels[1] = " + pixels[1] + "; pixels[10] = " + pixels[10]); Log.i("myBitmapDecode", "pixels[w] = " + pixels[w] + "; pixels[h] = " + pixels[h] + "; pixels[w*h-1] = " + pixels[w*h-1]);运行结果:
背景色设置(pixels[])
背景颜色与pixels[]初始值一致,如红色RED(-65536 0xffff0000),黄色YELLOW(-256 0xffffff00),具体详见下面附注
int[] pixels = new int[w*h]; for(int i=0; i<w*h; i++){ pixels[i] = -65536; // Color.RED : -65536 (0xffff0000) } mBitmap2.getPixels(pixels, 50, w, 50, 0, w/2, h/2); mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h, Bitmap.Config.ARGB_8888); Log.i("myBitmapDecode", "w = " + w + "; h = " + h); Log.i("myBitmapDecode", "pixels[0] = " + pixels[0] + "; pixels[1] = " + pixels[1] + "; pixels[10] = " + pixels[10] + "; pixels[50] = " + pixels[50]); Log.i("myBitmapDecode", "pixels[w] = " + pixels[w] + "; pixels[h] = " + pixels[h] + "; pixels[w*h-1] = " + pixels[w*h-1]); for(int i=0; i<w*h; i++){ pixels[i] = -256; // Color.YELLOW : -256 (0xffffff00) } mBitmap2.getPixels(pixels, 50*100 + 50, w, 50, 50, w/2, h/2); mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h, Bitmap.Config.ARGB_4444); Log.i("myBitmapDecode", "w = " + w + "; h = " + h); Log.i("myBitmapDecode", "pixels[0] = " + pixels[0] + "; pixels[1] = " + pixels[1] + "; pixels[10] = " + pixels[10] + "; pixels[50] = " + pixels[50]); Log.i("myBitmapDecode", "pixels[w] = " + pixels[w] + "; pixels[h] = " + pixels[h] + "; pixels[w*h-1] = " + pixels[w*h-1]);
运行结果:
I/myBitmapDecode( 1671): w = 100; h = 100
I/myBitmapDecode( 1671): pixels[0] = -65536; pixels[1] = -65536; pixels[10] = -65536; pixels[50] = -16777216
I/myBitmapDecode( 1671): pixels[w] = -65536; pixels[h] = -65536; pixels[w*h-1] = -65536
I/myBitmapDecode( 1671): w = 100; h = 100
I/myBitmapDecode( 1671): pixels[0] = -256; pixels[1] = -256; pixels[10] = -256; pixels[50] = -256
I/myBitmapDecode( 1671): pixels[w] = -256; pixels[h] = -256; pixels[w*h-1] = -16735513
示例如下:
int w = mBitmap2.getWidth(); int h = mBitmap2.getHeight(); int[] pixels = new int[2*w*h]; for(int i=0; i<2*w*h; i++){ pixels[i] = -2578654; } mBitmap2.getPixels(pixels, 0, 2*w, 0, 0, w, h); mBitmap2.getPixels(pixels, w, 2*w, 0, 0, w, h); mBitmap3 = Bitmap.createBitmap(pixels, 0, 2*w, 2*w, h, Bitmap.Config.ARGB_8888); String txt = String.valueOf(pixels[10]); Log.i("myBitmapDecode", "w = " + w + "; h = " + h); Log.i("myBitmapDecode", "pixels[0] = " + pixels[0] + "; pixels[1] = " + pixels[1] + "; pixels[10] = " + pixels[10]); Log.i("myBitmapDecode", "pixels[w] = " + pixels[w] + "; pixels[h] = " + pixels[h] + "; pixels[w*h-1] = " + pixels[w*h-1]); Log.i("myBitmapDecode", "pixels[2*w-1] = " + pixels[2*w-1] + "; pixels[2*w] = " + pixels[2*w] + "; pixels[2*w*h-1] = " + pixels[2*w*h-1]);运行结果:
最后,stride参数的意义及用处总结如下:
附注(Color颜色对应值):
1, int, int, int, int, int, int)]Android英文文档getPixels()方法介绍
3 StackOverflow中关于getPixels()问答.
4Using the LockBits method to access image data