简体   繁体   中英

How to read pixel data only not meta data from 16 bit image in c#?

I have 16 bit depth image from that I want to read only pixel data and store it to byte[]

I tried following code :

FileInfo fileInfo = new FileInfo("C:\\Image stitch API\\Temp\\output.tif");
byte[] data = new byte[fileInfo.Length];

I also tried the following :

Image img;
img = Image.FromFile("C:\\Image stitch API\\Temp\\output.tif");
ImageConverter ic = new ImageConverter();
byte[] data = (byte[])ic.ConvertTo(img, typeof(byte[]))

Here all data it is coming from image, but I need only pixel data?

Can any one help on this?

If you can load your image as Bitmap, it is pretty easy to get pixel info as shown below.

    Bitmap bitmap = new Bitmap("somefile.ext");
    Color color = bitmap.GetPixel(x,y) 

GetPixel() will return Color (struct) type and you can get individual channel values as byte like shown below.

    byte g = slateBlue.G;
    byte b = slateBlue.B;
    byte r = slateBlue.R;
    byte a = slateBlue.A;

Regarding your comment, I will suggest you to use use Netvips to manipulate image in byte array form (it is way betterand faster than system.drawing). By doing so, you could get image bands as byte arrays as below.

    var imageBands = inputImage.Bandsplit();
    var R = imageBands [0];
    var B = imageBands [1];
    var G = imageBands [2];

If you dont wanna switch the libraries, you could get byte array with System.Drawing like shown below.

byte[] image = new[] {R, B, G};

The fastest way to get image data out of an image is to use LockBits and Marshal.Copy .

I strongly advice against using GetPixel . See, LockBits works by reserving memory for putting the bytes of the image and copying the bytes of the image in there. UnlockBits will then clean up that reserved memory.

Now, the problem is, GetPixel performs this same locking and unlocking operation for every single pixel you access . Using LockBits once is fairly fast, but using it over and over for tens of thousands of pixels really slows things down.

Note that there are two ways of using LockBits ; either you get the data in the original pixel format, using sourceImage.PixelFormat , or you make LockBits convert the data to the format you require, by giving a different one. In this code, I force the output to the pixel format 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 can normally differ from width * bpp since lines of bitmaps are always aligned to multiples of 4 bytes, so normally you need to return that as well and keep track of it, but since this is a 32-bit format, its data is always aligned to 4 bytes, so there is never an actual difference here.

Note, your question never specifies the order in which you need the data. Typical ARGB data is actually in the byte order B, G, R, A, because normal integer saving on IBM PC architecture is little-endian, meaning that the actual bytes of an Int32 value "FFEEDDCC" are reversed in memory to [CC DD EE FF]. But your comment on the other answer given here seemed to indicate you went for byte order [RR, GG, BB, AA], or, 'ABGR', which is honestly not a format I've ever seen before. But if you do need to change that, it's just a simple extra loop to exchange red and blue:

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM