转载自:http://blog.csdn.net/jie_qing/article/details/7259520

在学习Graphics中遇到位图(Bitmap)中getPixels()方法,对该方法的用法大体理解,但对其中的stride参数却不明白具体的用法以及用意,经过一番折腾后,有些明了,现记述过程如下:

行文有些详细,请赶时间的同学直接跳到红字总结处查看!! 
getPixels()方法的用处为获取位图(Bitmap)中的根据方法参数所决定的像素值(颜色值),存入类型为int的pixels数组中,至于从RGB转换为int数值的算法是什么,暂时不知,存疑!!

Android英文SDK中有关getPixels()方法的介绍如下: 
(引自Android SDK官网,链接请见附后1)

public void getPixels (int[] pixels, int offset, int stride, int x, int y, int width, int height)

Since: API Level 1 
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. 
Parameters

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 
Throws

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. 

看完英文文档仍然不甚明白,于是去搜了下中文Android文档相应内容,如下(引自农民伯伯博客,链接请见附后2):

public void getPixels (int[] pixels, int offset, int stride, int x, int y, int width, int height)

把位图的数据拷贝到pixels[]中。每一个都由一个表示颜色值的int值来表示。幅度参数表明调用者允许的像素数组行间距。对通常的填充结果,只要传递宽度值给幅度参数。 
参数 
pixels      接收位图颜色值的数组 
offset      写入到pixels[]中的第一个像素索引值 
stride      pixels[]中的行间距个数值(必须大于等于位图宽度)。可以为负数 
x           从位图中读取的第一个像素的x坐标值。 
y           从位图中读取的第一个像素的y坐标值 
width      从每一行中读取的像素宽度 
height    读取的行数               
异常 
IilegalArgumentExcepiton       如果x,y,width,height越界或stride的绝对值小于位图宽度时将被抛出。 
ArrayIndexOutOfBoundsException          如果像素数组太小而无法接收指定书目的像素值时将被抛出。

看完后仍然对Stride解释中的"行间距"不太明白,去查了下Stride在英语中的原义 
Stride在柯林斯中的英英释义如下:

1 If you stride somewhere, you walk there with quick, long steps. 
  stride意为"大踏步快速前进" 
2 A stride is a long step which you take when you are walking or running. 
  stride在此做名词,意为"大步" 
3 Someone's stride is their way of walking with long steps. 
  指代某人具体迈大步的方式.

于是可以把stride理解为人行走过程中所迈大步的一段距离,而在此方法中可以理解为每行的像素数,至于用处是什么,还要继续寻找答案.

然后去StackOverFlow去搜了搜"getPixels() stride"关键字,查找到如下信息:

1  In most cases the stride is the same as the width. The stride is useful if you are trying to copy/draw a sub-region of a Bitmap. For instance, if you have a 100x100 bitmap and you want to draw the 50x50 top-right corner, you can use a width of 50px and a stride of 100px.(链接请见附后3)

2  Stride is number of bytes used for storing one image row.

Stride can be different from the image width.

Most of the images are 4 byte aligned.

For ex. a 24 bit (RGB) image with width of 50 pixels. The total bytes required will be 150 (3(RGB)*50). As image will be 4 byte aligned, in this case the byte required will become 154.

So you will see stride as 154, width 50 and image alignment as 4 byte.(链接请见附后3)

上面内容表示stride参数有两种用处

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

截 图:假设读取像素值的原图片宽为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图像(图上黄色部分)修改程序部分代码为:

Java代码  
  1. mBitmap2.getPixels(pixels, 0, w, 50, 0, w/2, h/2);
  2. String text = String.valueOf(pixels[10]);
  3. Log.i(SampleView.VIEW_LOG_TAG,text);
  4. mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h,
  5. Bitmap.Config.ARGB_8888);
  6. mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h,
  7. Bitmap.Config.ARGB_4444);

运行后得到如下结果:

现 在我们看到右边两副ARGB_8888,ARGB_4444图像隐约只在左上角显示原图右上的1/4黄色部分,其余部分为背景色白色,那么问题又来了,此 时ARGB_8888,ARGB_4444图像大小为多少?还是原图的大小(100*100)吗,或者是(50*50)了,不然背景色为何是画布的背景色 呢?那么把 
pixels[100*100]数组设初始值看下情况(通过Log.i()我查到了pixels中存储的像素值为百万左右的负整数,所以这里胡乱取个数-2578654做为初始值,颜色不太好,请见谅),修改后代码如下:

Java代码  
  1. int[] pixels = new int[w*h];
  2. for(int i=0; i < w*h; i++){
  3. pixels[i] = -2578654;
  4. }
  5. mBitmap2.getPixels(pixels, 0, w, 50, 0, w/2, h/2);
  6. String text = String.valueOf(pixels[10]);
  7. Log.i(SampleView.VIEW_LOG_TAG,text);
  8. mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h,
  9. Bitmap.Config.ARGB_8888);
  10. mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h,
  11. Bitmap.Config.ARGB_4444);

运行后结果为:

这样我们就可以看到结果了,如果pixels[]中的数值为int默认值(0)的话,图片相应的部分就为背景色,如果设置为别的初始值而在运行中没有被修改的话就还是原样.

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

Java代码  
  1. mBitmap2.getPixels(pixels, 50, w, 50, 0, w/2, h/2);

运行结果如下

当然可以用这个方法进行更复杂的运算,诸如截取素材图片修改目标图片(已存储至pixels数组中)的指定区域!!

图片拼接:

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

Java代码  
  1. int w = mBitmap2.getWidth();
  2. int h = mBitmap2.getHeight();
  3. int n = 2*w;
  4. Log.i(SampleView.VIEW_LOG_TAG,String.valueOf(w*h));
  5. int[] pixels = new int[n*h];
  6. for(int i=0; i < n*h; i++){
  7. pixels[i] = -2578654;
  8. }
  9. mBitmap2.getPixels(pixels, 0, n, 0, 0, w, h);
  10. mBitmap2.getPixels(pixels, w, n, 0, 0, w, h);
  11. mBitmap3 = Bitmap.createBitmap(pixels, 0, n, n, h,
  12. Bitmap.Config.ARGB_8888);

运行结果如下 
 

第二种:  
stride表示数组pixels[]中存储的图片每行的数据,在其中可以附加信息,即 
stride = width + padding,如下图所示(图片引自链接请见附后4)

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

最后,stride参数的意义及用处总结如下:

1  用来表示pixels[]数组中每行的像素个数,用于行与行之间区分,绝对值必须大于参数width,但不必大于所要读取图片的宽度w(在width < w 时成立).(stride负数有何作用不知,存疑).另,pixels.length >= stride * height,否则会抛出ArrayIndexOutOfBoundsException 异常

2 stride > width时,可以在pixels[]数组中添加每行的附加信息,可做它用.

附后: 
1, int, int, int, int, int, int)]Android英文文档getPixels()方法介绍

2 Android中文文档getPixels()方法介绍

3 StackOverflow中关于getPixels()问答.

4 图片来源

转载于:https://www.cnblogs.com/jackwuyongxing/p/3939333.html

Bitmap类getPixels()方法中参数stride理解相关推荐

  1. 使用反射获得jar包中的类、方法、参数、返回值类型,然后动态加载jar包运行方法

    其实我的需求是在系统中 测试用户导入的jar包,所有网上找了很多解决方案,踩过很多坑,再加上以前搞c++的,对java不是很熟, 这里特意记录下,算是基本满足需求了 使用反射获得jar包中的类.方法. ...

  2. 【学习笔记】28、类的方法及参数介绍

    类的方法及参数介绍 初始化方法 在类被实例化的时候,有一个方法会被自动运行,这个方法就是"__init__(self)" (前后两个下划线). 这个方法主要用于在一个对象被实例化的 ...

  3. SrpingMVC 映射方法中参数之value,param,同时使用出现的问题

    SrpingMVC 映射方法中参数 value,param,同时使用  总是这个数据驱动类的错很奇怪 后来修改了RequestMapping里的key好了 @RequestMapping(" ...

  4. java 中showinfo方法,jmockito模拟方法中参数如何指定

    在做单元测试的时候,经常会遇到mock类的方法的情景.在写单测过程中,遇到一些问题,比较困惑,便做了一些测试,并得出一个结论: 在mock类的方法时,当符合 (mock参数).equals(实际调用过 ...

  5. C#方法中参数ref和out的解析

    一.C#方法中参数类型 有4种参数类型,有时候很难记住它们的不同特征,下图对它们做一个总结,使之更容易比较和对照. 二.C#方法中的参数 1.值参数 使用值参数,通过复制实参的值到形参的方式把数据传递 ...

  6. js在类的方法中访问自己的属性

    在类的方法中访问自己的属性,Javascript对于公有属性和私有属性的访问方法有所不同,请大家看下面的代码 functionShape(ax,ay) { varx=0; vary=0; this.g ...

  7. OpenCV类VideoCapture构造函数中参数apiPreference的可选值及意义

    OpenCV类VideoCapture构造函数中参数apiPreference的可选值及意义 OpenCV的类VideoCapture有三种构造函数,原型如下. C++: cv::VideoCaptu ...

  8. 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    目录 前言 现象 源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍 HandlerMethodArgumen ...

  9. 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析] good

    目录 前言 现象 源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍 HandlerMethodArgumen ...

最新文章

  1. 如何获取元素最终使用的css值
  2. Redpine Signals RS9110-N-11-02 Wi-Fi解决方案
  3. 解决虚机中的Centos7连不上网
  4. 如何查看linux系统的体系结构
  5. 【转】Sobel 算子
  6. Atitit.软件开发的非功能性需求attilax 总结At
  7. 管理信息系统(学习笔记)
  8. 解压缩文件常用命令——linux
  9. 川西云南行散记之五《稻城-亚丁-洛绒牛场》
  10. 青龙面板-快手极速版(每天3块脚本)(废-已不能使用)
  11. Java笔记23反射,设计模式
  12. 计算机怎么不读u盘,老司机告诉你电脑不读U盘的解决方法
  13. Js基础引导(二)——语法
  14. zynqsd的读写数据_数据存储结构图 - Zynq7000 FPGA的高速信号采集处理平台的设计搭建以及后续拓展...
  15. 寒假每日一题 1 : 笨拙的手指 java
  16. Delong test比较两个ROC曲线的性能
  17. Retrofit自定义GsonConverter处理请求错误异常处理
  18. 机器学习中的数学——距离定义(二十):相对熵(Relative Entropy)/KL散度(Kullback-Leibler Divergence)
  19. python代码解释4个作用域_Python中作用域的深入讲解
  20. 【Web技术】1091- 跨浏览器窗口 ,7种方式,你还知道几种呢?

热门文章

  1. Testin云测试:QQ(4.2.0)安卓版客户端可用性优秀
  2. 在批处理中运行.sql文件
  3. [转]SupSite页面文件与模块关系说明
  4. ajax: PopupControlExtender使用
  5. ASP.NET Core EFCore 之Code First
  6. 【转】Linux查看物理CPU个数、核数、逻辑CPU个数
  7. 5-5 表格输出 (5分)
  8. BeautifulSoup库的使用
  9. mac 安装Android sdk以便开展appium android自动化测试
  10. std::ostringstream::str()返回临时对象