[C#在WindowsForm.PictureBox中显示RAW16灰度图像

问题描述 投票:0回答:1

我正在尝试将RAW16图像文件显示为简单的WindowsForm.PictureBox。这是我的代码:

using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;

private void btnSelect_Click(object sender, EventArgs e)
{
    if (dlgPicture.ShowDialog() == DialogResult.OK)
        txtPicture.Text = dlgPicture.FileName;
}

private void btnLoad_Click(object sender, EventArgs e)
    {
        if (System.IO.File.Exists(txtPicture.Text))
        {
            byte[] _data = System.IO.File.ReadAllBytes(txtPicture.Text);

            Bitmap _bmp = new Bitmap(160, 120, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale);
            Rectangle _rect = new Rectangle(0, 0, 160, 120);
            BitmapData _bmpData = _bmp.LockBits(_rect, ImageLockMode.WriteOnly, _bmp.PixelFormat);
            short[] _rawdata = new short[19200];

            for (int x = 0; x < 160; x++)
            {
                for (int y = 0; y < 120; y++)
                {
                    short _word;
                    int index;

                    index = (y*160)+x;

                    _word = (short)(_data[index]<<8 + _data[index+1]);
                    _rawdata[index] = _word;
                }
            }

            var _ptr = _bmpData.Scan0;
            Marshal.Copy(_rawdata, 0, _ptr, _rawdata.Length);
            _bmp.UnlockBits(_bmpData);
            pbFrame.Image = _bmp;
        }
    }

当我选择RAW16灰度图像时,结果是System.ArgumentException: Invalid parameter

示例图片文件在这里:Example RAW16 picture file

c# .net
1个回答
0
投票

修改SamAxe建议的链接中提供的代码,我这样写:

private void btnLoad_Click(object sender, EventArgs e)
{
    if (System.IO.File.Exists(txtPicture.Text))
    {
        byte[] _data = System.IO.File.ReadAllBytes(txtPicture.Text);

        var _rgbData = Convert16BitGrayScaleToRgb16(_data, 160, 120);
        var _bmp = CreateBitmapFromBytes(_rgbData, 160, 120);

        pbFrame.Image = _bmp;
    }
}

private static void Convert16bitGSToRGB(UInt16 color, out byte red, out byte green, out byte blue)
{
    red = (byte)(color & 0x31);
    green = (byte)((color & 0x7E0) >> 5);
    blue = (byte)((color & 0xF800) >> 11);
}

private static byte[] Convert16BitGrayScaleToRgb48(byte[] inBuffer, int width, int height)
{
    int inBytesPerPixel = 2;
    int outBytesPerPixel = 6;

    byte[] outBuffer = new byte[width * height * outBytesPerPixel];
    int inStride = width * inBytesPerPixel;
    int outStride = width * outBytesPerPixel;

    // Step through the image by row
    for (int y = 0; y < height; y++)
    {
        // Step through the image by column
        for (int x = 0; x < width; x++)
        {
            // Get inbuffer index and outbuffer index
            int inIndex = (y * inStride) + (x * inBytesPerPixel);
            int outIndex = (y * outStride) + (x * outBytesPerPixel);

            byte hibyte = inBuffer[inIndex + 1];
            byte lobyte = inBuffer[inIndex];

            //R
            outBuffer[outIndex] = lobyte;
            outBuffer[outIndex + 1] = hibyte;

            //G
            outBuffer[outIndex + 2] = lobyte;
            outBuffer[outIndex + 3] = hibyte;

            //B
            outBuffer[outIndex + 4] = lobyte;
            outBuffer[outIndex + 5] = hibyte;
        }
    }
    return outBuffer;
}

private static byte[] Convert16BitGrayScaleToRgb16(byte[] inBuffer, int width, int height)
{
    int inBytesPerPixel = 2;
    int outBytesPerPixel = 2;

    byte[] outBuffer = new byte[width * height * outBytesPerPixel];
    int inStride = width * inBytesPerPixel;
    int outStride = width * outBytesPerPixel;

    // Step through the image by row
    for (int y = 0; y < height; y++)
    {
        // Step through the image by column
        for (int x = 0; x < width; x++)
        {
            // Get inbuffer index and outbuffer index
            int inIndex = (y * inStride) + (x * inBytesPerPixel);
            int outIndex = (y * outStride) + (x * outBytesPerPixel);

            byte hibyte = inBuffer[inIndex];
            byte lobyte = inBuffer[inIndex+1];

            outBuffer[outIndex] = lobyte;
            outBuffer[outIndex+1] = hibyte;
        }
    }

    return outBuffer;
}

private static byte[] Convert16BitGrayScaleToRgb24(byte[] inBuffer, int width, int height)
{
    int inBytesPerPixel = 2;
    int outBytesPerPixel = 3;

    byte[] outBuffer = new byte[width * height * outBytesPerPixel];
    int inStride = width * inBytesPerPixel;
    int outStride = width * outBytesPerPixel;

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            int inIndex = (y * inStride) + (x * inBytesPerPixel);
            int outIndex = (y * outStride) + (x * outBytesPerPixel);

            byte hibyte = inBuffer[inIndex];
            byte lobyte = inBuffer[inIndex + 1];

            byte r, g, b;

            UInt16 color = (UInt16)(hibyte << 8 | lobyte);

            Convert16bitGSToRGB(color, out r, out g, out b);

            outBuffer[outIndex] = r;
            outBuffer[outIndex + 1] = g;
            outBuffer[outIndex + 2] = b;
        }
    }

    return outBuffer;
}

private static Bitmap CreateBitmapFromBytes(byte[] pixelValues, int width, int height)
{
    //Create an image that will hold the image data

    Bitmap bmp = new Bitmap(width, height, PixelFormat.Format16bppRgb565);

    //Get a reference to the images pixel data
    Rectangle dimension = new Rectangle(0, 0, bmp.Width, bmp.Height);
    BitmapData picData = bmp.LockBits(dimension, ImageLockMode.ReadWrite, bmp.PixelFormat);
    IntPtr pixelStartAddress = picData.Scan0;

    //Copy the pixel data into the bitmap structure
    Marshal.Copy(pixelValues, 0, pixelStartAddress, pixelValues.Length);

    bmp.UnlockBits(picData);
    return bmp;
}

但是结果仍然不令人满意。这是我应该得到的图片:

Original picture

这是使用Convert16BitGrayScaleToRgb48的结果:

enter image description here

这是使用Convert16BitGrayScaleToRgb16的结果:

GrayScaleToRgb16

© www.soinside.com 2019 - 2024. All rights reserved.