亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Bitmap 之 getPixels() 的 stride

系統(tǒng) 2036 0

學(xué)習(xí)Graphics中遇到位圖(Bitmap)中g(shù)etPixels()方法,對該方法的用法大體理解,但對其中的stride參數(shù)卻不明白具體的用法以及用意,現(xiàn)記述過程如下:

getPixels()方法的用處為獲取位圖(Bitmap)中的像素值(顏色值),存入類型為int的pixels數(shù)組中,至于從RGB轉(zhuǎn)換為int數(shù)值的算法是什么,暫時不知,存疑!!

Android英文SDK中有關(guān) getPixels() 方法的介紹如下

??

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.

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
IllegalArgumentException ArrayIndexOutOfBoundsException
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文檔相應(yīng)內(nèi)容, getPixels()

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

把位圖的數(shù)據(jù)拷貝到 pixels[] 中。每一個都由一個表示顏色值的 int 值來表示。幅度參數(shù)(stride)表明調(diào)用者允許的像素數(shù)組行間距。對通常的填充結(jié)果,只要傳遞寬度值給幅度參數(shù)。

參數(shù)

pixels 接收位圖顏色值的數(shù)組

offset 寫入到 pixels[] 中的第一個像素索引值

stride pixels[] 中的行間距個數(shù)值 ( 必須大于等于位圖寬度 ) 。可以為負(fù)數(shù)

x 從位圖中讀取的第一個像素的 x 坐標(biāo)值。

y 從位圖中讀取的第一個像素的 y 坐標(biāo)值

width 從每一行中讀取的像素寬度

height   讀取的行數(shù)

異常

IllegalArgumentExcepiton 如果 x y width height 越界或 stride 的絕對值小于位圖寬度時將被拋出。

ArrayIndexOutOfBoundsException 如果像素數(shù)組太小而無法接收指定書目的像素值時將被拋出。


看完后仍然對Stride解釋中的"行間距"不太明白,去查了下Stride在英語中的原義,Stride在柯林斯中的英英釋義如下

1 If you stride somewhere, you walk there with quick, long steps.
  stride意為"大踏步快速前進(jìn)"
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理解為人行走過程中所邁大步的一段距離,而在此方法中可以理解為每行的像素數(shù),至于用處是什么,還要繼續(xù)尋找答案.

然后去StackOverFlow去搜了搜" getPixels() stride "關(guān)鍵字,查找到如下信息

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.

上面內(nèi)容表示stride參數(shù)有兩種用處

第一種

可以截取圖片中部分區(qū)域或者圖片拼接.

截圖:假設(shè)讀取像素值的原圖片寬為w,高為h,此時設(shè)置參數(shù)pixels[w*h], 參數(shù)stride為 w ,參數(shù)offset為0,參數(shù)x ,y為截圖的起點位置,參數(shù)width和height為截圖的寬度和高度,則此方法運行后,返回的pixels[]數(shù)組中從pixels[0]至pixels[width*height-1]里存儲的是從圖片( x , y )處起讀取的截圖大小為width * height的像素值.
示例:修改Android SDK自帶的AipDemo程序中BitmapDecode示例,更換圖像為自制四角四色圖:


圖像大小為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]);
  

運行結(jié)果:
Bitmap 之 getPixels() 的 stride
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]數(shù)組設(shè)初始值看下情況(通過Log.i()我查到了pixels中存儲的像素值為百萬左右的負(fù)整數(shù)(-16777216),所以這里胡亂取個數(shù)-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]);
  

運行結(jié)果:

Bitmap 之 getPixels() 的 stride

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

我們可以看到結(jié)果了,如果pixels[]中的數(shù)值為int默認(rèn)值(0)的話,圖片相應(yīng)的部分就為背景色,如果設(shè)置為別的初始值而在運行中沒有被修改的話,背景色就是修改值對應(yīng)的RGB顏色.

原圖位置(offset)
下面設(shè)置下getPixels[]方法中offset,使得黃色部分截圖出現(xiàn)在它在原圖中的位置,

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]);
  

運行結(jié)果:
Bitmap 之 getPixels() 的 stride
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

當(dāng)然可以用這個方法進(jìn)行更復(fù)雜的運算,諸如截取素材圖片修改目標(biāo)圖片(已存儲至pixels數(shù)組中)的指定區(qū)域!!


背景色設(shè)置(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]);
  

運行結(jié)果:

Bitmap 之 getPixels() 的 stride

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


圖片拼接 :

假設(shè)兩張圖片大小都為 w * h ,getPixels()方法中設(shè)置參數(shù)pixels[2*w*h],參數(shù)offset = 0,stride = 2*w讀取第一張圖片,再次運行g(shù)etPixels()方法,設(shè)置參數(shù)offset = w,stride = 2*w,讀取第二張圖片,再將pixels[]繪制到畫布上就可以看到兩張圖片已經(jīng)拼接起來了.

示例如下:

    	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]);
  

運行結(jié)果:
Bitmap 之 getPixels() 的 stride
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表示數(shù)組pixels[]中存儲的圖片每行的數(shù)據(jù),在其中可以附加信息,即
stride = width + padding,如下圖所示
Bitmap 之 getPixels() 的 stride


這樣可以不僅僅存儲圖片的像素信息,也可以儲存相應(yīng)每行的其它附加信息.


最后,stride參數(shù)的意義及用處總結(jié)如下:


1 用來表示pixels[]數(shù)組中 每行的像素個數(shù) ,用于行與行之間區(qū)分,絕對值必須大于參數(shù)width,但不必大于所要讀取圖片的寬度w(在width < w 時成立).(stride負(fù)數(shù)有何作用不知,存疑).另,pixels.length >= stride * height,否則會拋出ArrayIndexOutOfBoundsException異常

2 stride > width時,可以在pixels[]數(shù)組中添加每行的附加信息,可做它用.




附注(Color顏色對應(yīng)值):

???????? Constants

public static final int BLACK

Constant Value: -16777216 (0xff000000)

public static final int BLUE

Constant Value: -16776961 (0xff0000ff)

public static final int CYAN

Constant Value: -16711681 (0xff00ffff)

public static final int DKGRAY

Constant Value: -12303292 (0xff444444)

public static final int GRAY

Constant Value: -7829368 (0xff888888)

public static final int GREEN

Constant Value: -16711936 (0xff00ff00)

public static final int LTGRAY

Constant Value: -3355444 (0xffcccccc)

public static final int MAGENTA

Constant Value: -65281 (0xffff00ff)

public static final int RED

Constant Value: -65536 (0xffff0000)

public static final int TRANSPARENT

Constant Value: 0 (0x00000000)

public static final int WHITE

Constant Value: -1 (0xffffffff)

public static final int YELLOW

Constant Value: -256 (0xffffff00)


引用參考:

1 , int, int, int, int, int, int)]Android英文文檔getPixels()方法介紹

3 StackOverflow中關(guān)于getPixels()問答.

4 Using the LockBits method to access image data



Bitmap 之 getPixels() 的 stride


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日本高中生一级乇片 | 欧美一区二区三区婷婷月色 | 日产精品一区二区 | 94在线| 久久国产精品亚洲 | 日韩毛片久久91 | 午夜一级毛片 | 国产香蕉免费精品视频 | 99r在线视频 | 成年女人18级毛片毛片免费观看 | 亚洲精品不卡午夜精品 | 亚洲在线网站 | 99九九成人免费视频精品 | 久久青草精品一区二区三区 | 久久国产亚洲高清观看5388 | 狠狠综合久久久久综 | a级毛片在线观看 | 国产一区二区三区免费看 | 国产精品久久现线拍久青草 | 亚洲欧洲毛片 | 天天躁夜夜躁很很躁麻豆 | 欧美国产片 | 欧美在线视频免费看 | 在线a网 | 亚洲七七久久精品中文国产 | 国产国拍亚洲精品福利 | 日日操日日 | 大杳焦伊人久久综合热 | 国产大片中文字幕在线观看 | 久久精品国产欧美日韩亚洲 | jiucao视频在线观看 | 国产欧美视频在线观看 | 天天干天天操天天 | 黄片一级毛片 | 中国一级特黄 | 欧美色欧美亚洲高清在线观看 | 97se在线| 久久黄色一级视频 | 天天综合亚洲国产色 | 久久久免费| 婷婷亚洲综合 |