簡體   English   中英

如何只讀取像素數據而不是c#中16位圖像的元數據?

[英]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};

從圖像中獲取圖像數據的最快方法是使用LockBitsMarshal.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM