在图片框中渲染16位图像

时间:2013-08-13 19:30:43

标签: c# picturebox pixel

我有一个数组,其中包含从Dicom Image中提取的PixelData。

以下是代码:

        byte[] bytes = img.PixelData.GetFrame(0).Data; // img is the Dicom Image
        int count = bytes.Length / 2;
        ushort[] words = new ushort[count];
        for (int i = 0, p = 0; i < count; i++, p += 2)
        {
            words[i] = BitConverter.ToUInt16(bytes, p);
        }
        pixels16 = words.ToList(); //pixels16 contains now the PixelData for the Grayscale image

现在,这是我的问题,如何将其渲染到Picturebox?

4 个答案:

答案 0 :(得分:1)

我将Bitmaps从Format16bppGrayScale转换为Format8bppIndexed格式的代码。 PictureBox可以轻松显示这种格式。 (如果需要,可以使用不同的调色板)。

public Bitmap Gray16To8bppIndexed(Bitmap BmpIn)
{
    if (BmpIn.PixelFormat != PixelFormat.Format16bppGrayScale)
        throw new BadImageFormatException();

    byte[] ImageData = new byte[BmpIn.Width * BmpIn.Height * 2];
    Rectangle Re = new Rectangle(0, 0, BmpIn.Width, BmpIn.Height);

    BitmapData BmpData = BmpIn.LockBits(Re, ImageLockMode.ReadOnly, BmpIn.PixelFormat);
    Marshal.Copy(BmpData.Scan0, ImageData, 0, ImageData.Length);
    BmpIn.UnlockBits(BmpData);

    byte[] ImageData2 = new byte[BmpIn.Width * BmpIn.Height];
    for (long i = 0; i < ImageData2.LongLength; i++)
        ImageData2[i] = ImageData[i * 2 + 1];
    ImageData = null;

    Bitmap BmpOut = new Bitmap(BmpIn.Width, BmpIn.Height, PixelFormat.Format8bppIndexed);
    BmpData = BmpOut.LockBits(Re, ImageLockMode.WriteOnly, BmpOut.PixelFormat);
    Marshal.Copy(ImageData2, 0, BmpData.Scan0, ImageData2.Length);
    BmpOut.UnlockBits(BmpData);
    ImageData2 = null;
    BmpData = null;

    ColorPalette GrayPalette = BmpOut.Palette;
    Color[] GrayColors = GrayPalette.Entries;
    for (int i = 0; i < GrayColors.Length; i++)
        GrayColors[GrayColors.Length - 1 - i] = Color.FromArgb(i, i, i);
    BmpOut.Palette = GrayPalette;

    return BmpOut;
}

答案 1 :(得分:0)

好吧,我不知道具体细节,因为它取决于你真正想要的方式(如果性能很重要,你需要创建自己的Bitmap子类,否则,Bitmap.SetPixel会正常工作)。

但实质上,您需要将这些像素推入Bitmap,然后将图片框的图像设置为该位图,如:

Bitmap bitmap = new Bitmap(width, height);

for(int y = 0;y < height;y++)
   for(int x = 0;x < width;x++)
       bitmap.SetPixel(x,y, Color.fromRGB(/* unpack your R,G,B channel of your pixel here */);

pictureBox.Image = bitmap;

答案 2 :(得分:0)

您可以使用AForge .NET Framework,它是一个很棒的.NET库,用于图像处理。使用System.Drawing.Imaging.PixelFormat.Format16bppGrayScale,内置的.NET Picturebox无法显示图像,但AForge库有自己的Picturebox控件,请查看此信息。它expects一个.NET Image。

您可以使用NuGet轻松地将AForge包含在您的项目中:

Install-Package AForge.Controls
Install-Package AForge.Imaging

或者只是

Install-Package AForge

以下示例代码:

//SOME BYTES
//Load here the DICOM image
int width=640, height=480;
int numberOfPixels = width*height;
byte[] source = new byte[2*numberOfPixels];

//With AFORGE
var image = AForge.Imaging.UnmanagedImage.Create(width, height, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale);
IntPtr ptrToImage = image.ImageData;
//Copies the bytes from source to the image
//System.Runtime.InteropServices
Marshal.Copy(source, 0, ptrToImage,numberOfPixels);

//WITH .NET
System.Drawing.Bitmap bitmapImage = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale);
var imageData = bitmapImage.LockBits(new System.Drawing.Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale);
Marshal.Copy(source, 0, imageData.Scan0, numberOfPixels);
bitmapImage.UnlockBits(imageData);   

答案 3 :(得分:0)

从朋友那里得到了这个想法。 inputImage.ImageSource 属性是一个包含灰度像素值的二维数组。

Bitmap grayscaleImage = new Bitmap(inputImage.ImageSource);
            for (int x = 0; x < grayscaleImage.Width; x++)
            {
                for (int y = 0; y < grayscaleImage.Height; y++)
                {
                    byte[,] tempMatrix = inputImage.ImageGrayscale;
                    byte temp = tempMatrix[x, y];
                    Color tempColor = Color.FromArgb(255, temp, temp, temp);
                    grayscaleImage.SetPixel(x, y, tempColor);
                }
            }
            picboxDisplay.Image = grayscaleImage;