[英]How to read pixel data only not meta data from 16 bit image in c#?
我有16位深度圖像,我只想讀取像素數據並將其存儲到byte []
我試過以下代碼:
FileInfo fileInfo = new FileInfo("C:\\Image stitch API\\Temp\\output.tif");
byte[] data = new byte[fileInfo.Length];
我也嘗試過以下方法:
Image img;
img = Image.FromFile("C:\\Image stitch API\\Temp\\output.tif");
ImageConverter ic = new ImageConverter();
byte[] data = (byte[])ic.ConvertTo(img, typeof(byte[]))
這里所有的數據來自圖像,但我只需要像素數據?
任何人都可以幫忙嗎?
如果您可以將圖像加載為Bitmap,則很容易獲得像素信息,如下所示。
Bitmap bitmap = new Bitmap("somefile.ext");
Color color = bitmap.GetPixel(x,y)
GetPixel()將返回Color(struct)類型,您可以將單個通道值作為字節獲取,如下所示。
byte g = slateBlue.G;
byte b = slateBlue.B;
byte r = slateBlue.R;
byte a = slateBlue.A;
關於你的評論,我建議你使用Netvips來操作字節數組形式的圖像(它比system.drawing更快)。 通過這樣做,您可以將圖像波段作為字節數組,如下所示。
var imageBands = inputImage.Bandsplit();
var R = imageBands [0];
var B = imageBands [1];
var G = imageBands [2];
如果您不想切換庫,可以使用System.Drawing獲取字節數組,如下所示。
byte[] image = new[] {R, B, G};
從圖像中獲取圖像數據的最快方法是使用LockBits
和Marshal.Copy
。
我強烈反對使用GetPixel
。 請參閱, LockBits
通過保留內存來放置圖像的字節並在那里復制圖像的字節。 然后, UnlockBits
將清理該保留的內存。
現在,問題是, GetPixel
對您訪問的每個像素執行相同的鎖定和解鎖操作。 使用LockBits曾經是相當快的,但使用它一遍又一遍的像素數以萬計真的會減慢速度。
請注意,有兩種方法可以使用LockBits
; 要么使用sourceImage.PixelFormat
獲取原始像素格式的數據,要么讓LockBits 將數據轉換為您需要的格式,方法是給出不同的格式。 在此代碼中,我強制輸出為像素格式Format32bppArgb
。
/// <summary>
/// Gets the raw bytes from an image.
/// </summary>
/// <param name="sourceImage">The image to get the bytes from.</param>
/// <returns>The raw bytes of the image</returns>
public static Byte[] GetImageDataAs32bppArgb(Bitmap sourceImage)
{
BitmapData sourceData = sourceImage.LockBits(
new Rectangle(0, 0, sourceImage.Width, sourceImage.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
Byte[] data = new Byte[sourceData.Stride * sourceImage.Height];
Marshal.Copy(sourceData.Scan0, data, 0, data.Length);
sourceImage.UnlockBits(sourceData);
return data;
}
Stride
通常可以與width * bpp
不同,因為位圖行總是與4個字節的倍數對齊,所以通常你需要返回它並跟蹤它,但由於這是一個32位格式,它的數據總是對齊到4個字節,所以這里從來沒有實際的區別。
請注意,您的問題從不指定您需要數據的順序 。 典型的ARGB數據實際上是字節順序B,G,R,A,因為IBM PC體系結構上的正常整數保存是小端的,這意味着Int32值“FFEEDDCC”的實際字節在內存中被反轉為[CC DD EE FF]。 但你對這里給出的另一個答案的評論似乎表明你選擇了字節順序[RR,GG,BB,AA],或'ABGR',這實際上不是我以前見過的格式。 但是如果你確實需要改變它,它只是一個簡單的額外循環來交換紅色和藍色:
for (Int32 i = 0; i < data.Length; i += 4)
{
Byte b = data[i]; // save Blue
data[i] = data[i + 2]; // set first component to the Red value
data[i + 2] = b; // set third component to the Blue value
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.