学习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.
pixels | The array to receive the bitmap's colors |
---|---|
offset | The first index to write into pixels[] |
stride | The number of entries in pixels[] to skip between rows (must be >= bitmap's width). Can be negative. |
x | The x coordinate of the first pixel to read from the bitmap |
y | The y coordinate of the first pixel to read from the bitmap |
width | The number of pixels to read from each row |
height | The number of rows to read |
IllegalArgumentException | if x, y, width, height exceed the bounds of the bitmap, or if abs(stride) < width. |
---|---|
ArrayIndexOutOfBoundsException | 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颜色对应值):
Constants
1, int, int, int, int, int, int)]Android英文文档getPixels()方法介绍
3 StackOverflow中关于getPixels()问答.
4 Using the LockBits method to access image data