`
android_mylove
  • 浏览: 399690 次
社区版块
存档分类
最新评论

Bitmap 之 getPixels() 的 stride

 
阅读更多

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

getPixels()方法的用处为获取位图(Bitmap)中的像素值(颜色值),存入类型为int的pixels数组中,至于从RGB转换为int数值的算法是什么,暂时不知,存疑!!

Android英文SDK中有关getPixels()方法的介绍如下



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 offset stride x y width height
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
Throws
IllegalArgumentExceptionArrayIndexOutOfBoundsException
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.


看完英文文档仍然不甚明白,于是去搜了下中文Android文档相应内容,getPixels()

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 如果xywidthheight越界或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.(注:stride绝对值要大于等于位图的宽度)

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.

上面内容表示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图像(图上黄色部分)修改程序部分代码为:

运行结果:

I/myBitmapDecode( 660): w = 100; h = 100
I/myBitmapDecode( 660): pixels[0]-16777216; pixels[1] = -16777216;
pixels[10] = -4352
I/myBitmapDecode( 660): pixels[w]-16777216; pixels[h] = -16777216; pixels[w*h-1] = 0

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

运行结果:


I/myBitmapDecode( 727): w = 100; h = 100
I/myBitmapDecode( 727): pixels[0] = -16777216; pixels[1] = -16777216;
pixels[10] = -4352
I/myBitmapDecode( 727): pixels[w] = -16777216; pixels[h] = -16777216; pixels[w*h-1] = -2578654

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

原图位置(offset)
下面设置下getPixels[]方法中offset,使得黄色部分截图出现在它在原图中的位置,

offset = x + y*w ,本例代码如下:

运行结果:

I/myBitmapDecode( 761): w = 100; h = 100
I/myBitmapDecode( 761): pixels[0] = -2578654; pixels[1] = -2578654;
pixels[10] = -2578654
I/myBitmapDecode( 761): pixels[w] = -2578654; pixels[h] = -2578654; pixels[w*h-1] = -2578654

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


背景色设置(pixels[])

背景颜色与pixels[]初始值一致,如红色RED(-65536 0xffff0000),黄色YELLOW(-256 0xffffff00),具体详见下面附注

运行结果:


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


图片拼接:

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

示例如下:

运行结果:

I/myBitmapDecode( 989): w = 100; h = 100
I/myBitmapDecode( 989): pixels[0] = -16777216; pixels[1] = -16777216;
pixels[10] = -16777216
I/myBitmapDecode( 989): pixels[w] = -16777216; pixels[h] = -16777216; pixels[w*h-1] = -16777216
I/myBitmapDecode( 989): pixels[2*w-1] = -3328; pixels[2*w] = -16777216; pixels[2*w*h-1] = -16735513

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



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


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


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

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




附注(Color颜色对应值):

Constants

public static final intBLACK

Constant Value:-16777216 (0xff000000)

public static final intBLUE

Constant Value:-16776961 (0xff0000ff)

public static final intCYAN

Constant Value:-16711681 (0xff00ffff)

public static final intDKGRAY

Constant Value:-12303292 (0xff444444)

public static final intGRAY

Constant Value:-7829368 (0xff888888)

public static final intGREEN

Constant Value:-16711936 (0xff00ff00)

public static final intLTGRAY

Constant Value:-3355444 (0xffcccccc)

public static final intMAGENTA

Constant Value:-65281 (0xffff00ff)

public static final intRED

Constant Value:-65536 (0xffff0000)

public static final intTRANSPARENT

Constant Value:0 (0x00000000)

public static final intWHITE

Constant Value:-1 (0xffffffff)

public static final intYELLOW

Constant Value:-256 (0xffffff00)


引用参考:

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

3 StackOverflow中关于getPixels()问答.

4Using the LockBits method to access image data



分享到:
评论

相关推荐

    Android Bitmap.getPixels的正确理解演示源码

    Android Bitmap.getPixels的正确理解演示源码,参考文章《Android Bitmap入门:getPixels的正确理解》

    Android利用BitMap获得图片像素数据的方法

    3. `stride`:数组中每一行像素数据之间的步长,通常设置为Bitmap的宽度。 4. `x` 和 `y`:从 Bitmap 的左上角开始的起始坐标。 5. `width` 和 `height`:要复制的像素区域的宽和高。 `getPixels()` 方法会从指定...

    C# Bitmap转RGB32(NI)

    int stride = originalData.Stride; byte[] pixels = new byte[bitmap.Width * bitmap.Height * 4]; Marshal.Copy(originalData.Scan0, pixels, 0, pixels.Length); for (int i = 0; i ; i += 4) { // 对于没有...

    Android 实现把bitmap图片的某一部分的颜色改成其他颜色

    在 Android 中,我们可以使用 Bitmap 类来处理 bitmap 图片,该类提供了多种方法来处理 bitmap 图片,例如 getPixels() 方法可以获取 bitmap 图片的像素颜色值,setPixels() 方法可以设置 bitmap 图片的像素颜色值。...

    bitmap上传图片demo

    在Android开发中,Bitmap是处理图像数据的基本类,它用于表示位图图像。"bitmap上传图片demo"是一个示例项目,展示了如何利用Bitmap处理本地图片并进行上传,同时提供了将图片裁剪为圆形以适合作为头像的功能。在这...

    Android下利用Bitmap切割图片

    在Android开发中,Bitmap是处理图像的基本类,用于在内存中表示位图图像。当我们需要对图片进行裁剪、缩放或进行其他操作时,Bitmap提供了丰富的功能。本篇文章将详细探讨如何在Android环境下利用Bitmap来切割图片。...

    Android canvas drawBitmap方法详解及实例

    `drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)`是`drawBitmap()`方法的一个重载版本,其参数含义如下: 1. **Bitmap bitmap**: 这是你要绘制的位图对象,通常是从资源文件、内存缓存或者直接创建的...

    Activity跳转时传递Bitmap对象

    在Android开发中,Activity之间的数据传递是常见的操作,特别是在处理图像数据时,如Bitmap对象。Bitmap是Android系统中用于表示图像的重要类,它包含了图像的所有像素信息。在不同Activity之间传递Bitmap,通常是...

    c#Bitmap类和Graphics类

    C#中的Bitmap类和Graphics类 C#中的Bitmap类和Graphics类是两种常用的图形处理类,它们之间存在一定的差异和联系。在本节中,我们将详细介绍Bitmap类和Graphics类的概念、方法和应用场景。 一、Bitmap类 Bitmap类...

    Android-使用Matrix对Bitmap进行处理

    Bitmap rotatedBitmap = Bitmap.createBitmap(originalBitmap, 0, 0, originalBitmap.getWidth(), originalBitmap.getHeight(), matrix, true); ``` 除了旋转,我们还可以使用Matrix进行缩放操作。例如,将Bitmap按...

    C#中bitmap、stream、byte类型转换实例

    在处理图像时,我们可能会遇到需要在不同的数据类型之间转换的情况,比如从Bitmap到Stream,再到byte数组,最后再还原回Bitmap。这样的转换在上传图片、存储图片数据或在网络中传输时非常常见。本篇文章将详细介绍...

    canvas 转换成bitmap

    "Android 中 Canvas 转换为 Bitmap" Android 中 Canvas 转换为 Bitmap 是一种常见的需求,especially 在需要将 Canvas 绘制的图形显示在 ImageView 中的情况下。在这篇文章中,我们将详细介绍如何将 Canvas 转换为 ...

    处理bitmap内存溢出问题

    在Android开发中,处理`Bitmap`内存溢出问题是一个常见的挑战,尤其是在处理高分辨率或大尺寸图片时。当应用程序尝试加载或操作一张超出虚拟机内存预算的`Bitmap`时,系统会抛出`java.lang.OutOfMemoryError: bitmap...

    android中对Bitmap图片设置任意角为圆角

    在Android开发中,Bitmap是用于表示图像数据的基本对象,它是一种内存中的图片表示形式。而当我们需要在应用程序中展示带有圆角的图片时,通常会用到Bitmap的处理技巧。本篇文章将深入探讨如何在Android中对Bitmap...

    c#.net Bitmap类的基本使用方法

    在C#.NET编程环境中,`Bitmap`类是用于处理图像的核心类,它允许开发者创建、加载、修改和显示位图图像。本篇文章将详细介绍`Bitmap`类的基本使用方法,包括其构造函数、属性、方法以及如何与其他图形组件交互。 1....

    将Bitmap转换为Byte[]

    在VC(Visual C++)环境下,Bitmap对象是用于表示图像的一种常见数据结构,而`Byte[]`(字节数组)则常用于数据传输或存储。本篇文章将详细解释如何在VC中将Bitmap对象转换为Byte数组。 首先,理解Bitmap对象。...

    Android中Glide获取图片Path、Bitmap用法详解

    软件开发网在此之前给大家介绍过图片加载框架Glide的基本用法介绍,大家可以先参考一下,本篇内容更加深入的分析了Glide获取图片Path、Bitmap用法,以及实现的代码分析。 1. 获取Bitmap: 1)在图片下载缓存好之后...

    Bitmap格式说明文档

    Bitmap文件格式是Windows操作系统中使用的图形文件格式之一。 二、Bitmap文件格式 Bitmap文件是存储在设备独立位图(DIB)格式中的,允许Windows在任何类型的显示设备上显示位图。设备独立意味着位图指定像素颜色在...

    Android中把bitmap存成BMP格式图片的方法

    在示例代码中,我们先通过`getDrawingCache()`方法获取View的绘制缓存,然后调用`getPixels()`方法得到Bitmap的像素数据。像素数据通常存储在一个整型数组中,每个像素由红、绿、蓝三原色的值表示。 2. **处理BMP...

    Bitmap图像转halcon图像

    而Bitmap图像则是一种常见的图像格式,广泛存在于Windows操作系统和其他多种环境中。在进行机器视觉项目时,有时我们需要将Bitmap图像转换为Halcon能识别的图像类型,即HObject,以便在Halcon中进行后续的图像分析和...

Global site tag (gtag.js) - Google Analytics