Bitmap类getPixels()详解

转载请标明出处:http://blog.csdn.net/xx326664162/article/details/52240795 文章出自:薛瑄的博客

你也可以查看我的其他同类文章,也会让你有一定的收货

getPixels()

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 returned colors are non-premultiplied ARGB values.

Parameters

参数名
pixels int: The array to receive the bitmap’s colors
offset int: The first index to write into pixels[]
stride int: The number of entries in pixels[] to skip between rows (must be >= bitmap’s width). Can be negative.
x int: The x coordinate of the first pixel to read from the bitmap
y int: The y coordinate of the first pixel to read from the bitmap
width int: The number of pixels to read from each row
height int: The number of rows to read

getPixels()函数把一张图片,从指定的偏移位置(offset),指定的位置(x,y)截取指定的宽高(width,height ),把所得图像的每个像素颜色转为int值,存入pixels。

stride 参数指定在行之间跳过的像素的数目。图片是二维的,存入一个一维数组中,那么就需要这个参数来指定多少个像素换一行。

可能有的人有疑问了,直接使用参数中的width,不就可以了,干嘛还要stride参数???

下面来看看stride参数的两种用处,这个问题你就会明白

stride参数两种用处

第一种:

可以截取图片中部分区域或者图片拼接.

1.1、截图:

假设读取像素值的原图片宽为w,高为h,此时设置参数pixels[w* h], 参数stride为 w ,参数offset为0,参数x ,y为截图的起点位置,参数width和height为截图的宽度和高度,

则此方法运行后,返回的pixels[]数组中从pixels[0]至pixels[width*height-1]里存储的是从图片( x , y )处起读取的截图大小为width * height的像素值.

示例:修改Android SDK自带的AipDemo程序中BitmapDecode示例,更换图像为自制四角四色图:

这里写图片描述

图像大小为100*100,想截取图片右上1/4图像(图上黄色部分)修改程序部分代码为:

//截取图片
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);

这里写图片描述

  • 生成的图片尺寸大小是由Bitmap.createBitmap()中的第4、5个参数决定的。

1.2、改变offset

下面设置下getPixels()方法中offset,使得黄色部分截图出现在它在原图中的位置, offset = x + y*w ,本例代码如下:

显示在右上角

offset = 50 + 0* 100

mBitmap2.getPixels(pixels, 50, w, 50, 0, w/2, h/2); 

这里写图片描述

显示在右下角

offset = 50 + 50* 100

mBitmap2.getPixels(pixels, 5050, w, 50, 0, w/2, h/2); 

这里写图片描述

getPixels()是把二维的图片的每一行像素颜色值读取到一个一维数组中
offset指明了所截取的图片的第一个像素的起始位置,如果显示在右下角,起始坐标是(50,50),这个点就是第50行,再移动50个像素,每行100个像素,所以在一维数组中的位置就是50+50*100

1.3、改变stride

先给出stride的结论,

  • 在原图上截取的时候,需要读取stride个像素再去读原图的下一行
  • 如果一行的像素个数足够,就读取stride个像素再下一行读
  • 如果一行的像素个数不够,用0(透明)来填充到 stride个
  • 得到的数据,依次存入pixels[]这个一维数组中

stride 设置为宽度的1/2

mBitmap2.getPixels(pixels, 0, w/2, 50, 0, w/2, h/2); 

这里写图片描述

stride 设为宽度的一半,上面的代码在截取原图的时候就是从(50,0)的位置读取一半然后换行,一直这样,直到读取够指定的宽高(w/2, h/2),把这些数据存储到pixels[]中,所以在pixels[]的前2500个整数存储的是黄色区块的信息。

stride 设置为宽度的2倍

mBitmap2.getPixels(pixels, 0, w/2, 50, 0, w/2, h/2); 

这里写图片描述

stride 设为宽度的2倍,上面的代码在截取原图的时候就是从(50,0)的位置读取2w个像素然后换行,但是指定读取的宽度为w/2,所以剩下的w3/2个值用0填充。一直这样,直到读取够指定的宽高(w/2, h/2),把这些数据存储到pixels[]中,所以在pixels[]中存储的是{ w/2个黄色区块信息,w3/2个透明值 ,w/2个黄色区块信息,w3/2个透明值 ,…}

所以看到左边的黄色,感觉颜色变淡了,就是因为有透明颜色参杂进来

stride 设置为宽度的3/2倍

mBitmap2.getPixels(pixels, 0, w*3/2, 50, 0, w/2, h/2); 

这里写图片描述

这个和上面的解释一样,下面来张大图,让你更好观察

这里写图片描述

stride 设置为宽度的3/2倍,起始位置为(0,0)

参数stride和width到底有什么区别,看完下面这个例子,相信你会恍然大悟

截取的是原图左上角部分,stride = w*3/2;

mBitmap2.getPixels(pixels, 0, w*3/2, 0, 0, w/2, h/2); 

这里写图片描述

另,pixels.length >= stride * height,否则会抛出ArrayIndexOutOfBoundsException 异常

2: 图片拼接

假设两张图片大小都为 w * h ,getPixels()方法中设置参数pixels[2wh],参数offset = 0,stride = 2w读取第一张图片,再次运行getPixels()方法,设置参数offset = w,stride = 2w,读取第二张图片,再将pixels[]绘制到画布上就可以看到两张图片已经拼接起来了.

int w = mBitmap2.getWidth();  
            int h = mBitmap2.getHeight();  
            int n = 2*w;  
            Log.i(SampleView.VIEW_LOG_TAG,String.valueOf(w*h));  
            int[] pixels = new int[n*h];  
            for(int i=0; i < n*h; i++){  
                pixels[i] = -2578654;  
            }  
            mBitmap2.getPixels(pixels, 0, n, 0, 0, w, h);  
            mBitmap2.getPixels(pixels, w, n, 0, 0, w, h);  
            mBitmap3 = Bitmap.createBitmap(pixels, 0, n, n, h,  
                                           Bitmap.Config.ARGB_8888); 

运行结果如下 :

这里写图片描述

第二种:

stride表示数组pixels[]中存储的图片每行的数据,在其中可以附加信息,即
stride = width + padding,如下图所示

这里写图片描述

这样可以不仅仅存储图片的像素信息,也可以储存相应每行的其它附加信息.

  • stride > width时,可以在pixels[]数组中添加每行的附加信息,可做它用.在使用Bitmap.createBitmap()创建新图时,需要考虑新图尺寸的大小

参考:
http://ranlic.iteye.com/blog/1313735 这篇博客中,作者似乎没有stride 的真正含义,在最后的结论一中,“用来表示pixels[]数组中每行的像素个数,用于行与行之间区分”,这句话理解是错误的。
[getPixels()官方文档](https://developer.android.com/reference/android/graphics/Bitmap.html#getPixels(int[], int, int, int, int, int, int))

关注我的公众号,轻松了解和学习更多技术
这里写图片描述

©️2020 CSDN 皮肤主题: 撸撸猫 设计师: 设计师小姐姐 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值