Grayscale image from binary data

丶灬走出姿态 提交于 2021-02-08 08:58:22

问题


I'm working on some simple viewer app for CT images. Let's say I have array of 262144 Int16 values.

Each value represents one pixel in 512x512 image. Each pixel has value from 0 to 4096 where 0 is black and 4096 is white.

Is there any elegant, simple solution to display this image in Visual Studio Picture Box? Maybe some kind of MemoryReader or Stream?

I've tried to search for some solution but found only topic about retrieving binary data from databases.


回答1:


A good way and with a good performance is to use LockBits function to access image data, using the LockBits you can create a Bitmap image using each byte of image, the lockBit lock the image data in memory to change each pixel data of the Bitmap Image. See this example:

  Bitmap bm = new Bitmap(512, 512);
  BitmapData bmd=bm.LockBits(new Rectangle(0, 0, 10, 10), System.Drawing.Imaging.ImageLockMode.ReadOnly, bm.PixelFormat);
  int PixelSize=4;

  for(int y=0; y<bmd.Height; y++)
  {
    byte* row=(byte *)bmd.Scan0+(y*bmd.Stride);
    for(int x=0; x<bmd.Width; x++)
    {
      // Here you change your pixel data
      row[x*PixelSize]=255;
    }
  }
  bm.UnlockBits(bmd)

to draw in pictureBox you can just concatenate the member Image of pictureBox, or draw of a manually way. See these examples:

// concatenate 
pict1.Image = bmp;

or

// Draw using CreateGraphics
Graphics g = Graphics.FromHwnd(pictureBox1.Handle);
g.DrawImage(bmp, new Point(10, 10));

About the grayscale you can get a grayscale just using the value of one channel of image or getting an average value between RGB values and use the same value to these three channels, see this example:

// Average value between channels
Color oc = bmp.GetPixel(i, x);
int grayScale = (int)((oc.R * 0.3) + (oc.G * 0.59) + (oc.B * 0.11));
Color nc = Color.FromArgb(oc.A, grayScale, grayScale, grayScale);
d.SetPixel(x, y, nc); // if you are using bitmap

or

// value from one channel
Color pixelColor = c.GetPixel(x, y);
Color newColor = Color.FromArgb(pixelColor.R, pixelColor.R, pixelColor.R);
c.SetPixel(x, y, newColor); // Now greyscale

See more about the lockBits in this link: https://web.archive.org/web/20141229164101/http://bobpowell.net/lockingbits.aspx

and about grayscale: https://en.wikipedia.org/wiki/Grayscale




回答2:


Thanks for a really helpful informations. I've managed to do it by myself

my code:

// stworzenie obrazu i przeskalowanie
    public Bitmap GetBitmap(double scalingFactor)
    {
        Bitmap image = new Bitmap(_width, _height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);

        // konwersja palety idexed na skale szarosci
        ColorPalette grayPalette = image.Palette;
        Color[] entries = grayPalette.Entries;
        for (int i = 0; i < 256; i++)
        {
            Color grayC = new Color();
            grayC = Color.FromArgb((byte)i, (byte)i, (byte)i);
            entries[i] = grayC;
        }
        image.Palette = grayPalette;

        // wrzut binary data do bitmapy
        BitmapData dataR = image.LockBits(new Rectangle(Point.Empty, image.Size), ImageLockMode.WriteOnly, image.PixelFormat);
        Marshal.Copy(_rawDataPresented, 0, dataR.Scan0, _rawDataPresented.Length);
        image.UnlockBits(dataR);

        // skalowanie wielkosci
        Size newSize = new Size((int)(image.Width * scalingFactor), (int)(image.Height * scalingFactor));
        Bitmap scaledImage = new Bitmap(image, newSize);

        return scaledImage;
    }


来源:https://stackoverflow.com/questions/27689739/grayscale-image-from-binary-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!