2014-12-29 5 views
0

Я работаю над некоторым простым приложением для просмотра изображений CT. Предположим, у меня есть массив из 262144 значений Int16.Изображение в оттенках серого из двоичных данных

Каждое значение представляет один пиксель в изображении 512x512. Каждый пиксель имеет значение от 0 до 4096, где 0 - черный, а 4096 - белый.

Есть ли элегантное, простое решение для отображения этого изображения в Visual Studio Picture Box? Может быть, какой-то MemoryReader или Stream?

Я попытался найти какое-то решение, но нашел только тему об извлечении двоичных данных из баз данных.

ответ

0

Хороший способ и с хорошей производительностью - использовать функцию LockBits для доступа к данным изображения, используя LockBits, вы можете создавать растровое изображение с использованием каждого байта изображения, lockBit блокирует данные изображения в памяти для изменения данных каждого пикселя изображения растрового изображения. Смотрите пример:

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) 

рисовать в PictureBox вы можете просто сцепить член Изображение PictureBox, или сделать из вручную путем. Смотрите следующие примеры:

// concatenate 
pict1.Image = bmp; 

или

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

О оттенках серого можно получить оттенки серого цвета только с использованием значения одного канала изображения или получить среднее значение между значениями RGB и использовать то же самое значение для эти три канала, см этот пример:

// 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 

или

// 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 

Подробнее о LockBits в этой ссылке: http://bobpowell.net/lockingbits.aspx

и о оттенках серых: http://en.wikipedia.org/wiki/Grayscale

0

Спасибо за очень полезную информацию. я сумел сделать это сам

мой код:

// 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; 
    }