2013-10-02 99 views
1

我有一個jpeg圖像。我將這個bitmapdata保存到一個字節數組中。從圖像字節數組中讀取像素

此JPEG具有100的寬度和100

我想提取Rectanlge的圖像(10,10,20,20)的高度;

顯然,我可以通過這個字節數組進行交互,但我不確定如何將我想要的x,y像素與這個字節數組關聯起來。我知道我必須使用步幅和像素大小,因爲它是rgba。

我有這個這是從這個鏈接cropping an area from BitmapData with C#

Bitmap bmp = new Bitmap(_file); 
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 
BitmapData rawOriginal = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb); 

int origByteCount = rawOriginal.Stride * rawOriginal.Height; 
byte[] origBytes = new Byte[origByteCount]; 
System.Runtime.InteropServices.Marshal.Copy(rawOriginal.Scan0, origBytes, 0, origByteCount); 

int BPP = 4; 
int width = 20; 
int height = 20; 
int startX = 10; 
int startY = 10; 

for (int i = 0; i < height; i++) 
{ 
for (int j = 0; j < width * BPP; j += BPP) 
{ 
int origIndex = (startX * rawOriginal.Stride) + (i * rawOriginal.Stride) + (startY * BPP) + (j); 
int croppedIndex = (i * width * BPP) + (j); 
         //copy data: once for each channel 
for (int k = 0; k < BPP; k++) 
{ 
croppedBytes[croppedIndex + k] = origBytes[origIndex + k]; 
} 
} 
} 

但這:

int origIndex = (startX * rawOriginal.Stride) + (i * rawOriginal.Stride) + (startY * BPP) + (j); 

我發現不正確。

有人知道我應該在這裏設置什麼樣的價值嗎?

感謝

回答

1

當你使用位圖數據乘工作x,有2件重要的事情要記住:

  1. 的BPP(每像素字節):在這裏是4
  2. 的STRI德(字節對圖像的一行數),在這裏將是4×寬

,所以如果你想有一個像素的得到補償,只要使用這個公式:

int offset = x * BPP + y * stride; 

如果你只想提取一部分位圖,你可以這樣做:

int i = 0; 

for(int y = startY; y < startY + height; y++) 
{ 
    for(int k = startX * bpp + y * stride; k < (startX + width) * bpp + y * stride; k++) 
    { 
     croppedBytes[i] = origBytes[k]; 
     i++; 
    } 
} 
+1

「這裏是4 *寬度」 - 不太完美,請注意''Stride'不是**總是'BPP * Width'。可能有一些填充取決於寬度,請參閱:http://stackoverflow.com/a/5736076/360211 – weston

+0

@weston這是真的,但不適用於32位圖像(至少現在),所以這裏確實是'4 *寬度。我不認爲位圖操作類是針對64位處理器進行了優化的,這就是爲什麼我非常懷疑可以填充32位圖像的問題。 – ppetrov

+0

哦,是的,我糾正了(對於32位圖像)。 – weston

1

Stride是每行(Y)字節,你不應該在任何時候通過Stride

int y = startY + i; 
int x = startX; 
int origIndex = y * rawOriginal.Stride + x * BPP; 
+0

嗨,感謝您的回覆。我不知道該怎麼辦。我最終自己找到了答案。但你和@ppetrov都是正確的,應該得到一個綠色的勾號。但我只能做1滴答。我應該在這裏發表這個問題嗎? –

+1

不要問,在這裏,像http://meta.stackoverflow.com這樣的問題。通常我會獎給第一個人。 ppetrov有更多的細節,所以如果這對你有幫助,請給他打勾。但是,無論您選擇哪個人,只要點擊每個答案旁邊的灰色向上箭頭,就可以隨時爲我們提供幫助。 – weston