2013-12-26 2 views
1

Я хотел бы получить информацию о цвете моего 64bpp изображения с помощью BitmapData. Я успешно сделал это для 32BPP изображений, но это, кажется, не быть столь же легким для 64bpp изображений ...Получить цвет изображения 64bpp

static void Main(string[] args) 
{ 
    Bitmap bmp; 
    using (Stream imageStreamSource = new FileStream(bitmapPath, FileMode.Open, FileAccess.Read, FileShare.Read)) //Should I use "using" here? or do I need to keep the stream open for as long as I use the Bitmap? 
    { 
     PngBitmapDecoder decoder = new PngBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); 
     BitmapSource bitmapSource = decoder.Frames[0]; 
     bmp = _bitmapFromSource(bitmapSource); 
    } 

    unsafe 
    { 
     int xIncr = Image.GetPixelFormatSize(bmp.PixelFormat)/8;  //8 
     xIncr /= 2; 

     BitmapData bData1 = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat); 

     ushort* bData1Scan0Ptr = (ushort*)bData1.Scan0.ToPointer(); 
     ushort* nextBase = bData1Scan0Ptr + bData1.Stride; 

     for (int y = 0; y < bData1.Height; ++y) 
     { 
      for (int x = 0; x < bData1.Width; ++x) 
      { 
       var red = bData1Scan0Ptr[2]; 
       var green = bData1Scan0Ptr[1]; 
       var blue = bData1Scan0Ptr[0]; 

       bData1Scan0Ptr += xIncr;  //xIncr = 4 
      } 

      bData1Scan0Ptr = nextBase; 
      nextBase += bData1.Stride; 
     } 
    } 
} 

//http://stackoverflow.com/questions/7276212/reading-preserving-a-pixelformat-format48bpprgb-png-bitmap-in-net 
private static Bitmap _bitmapFromSource(BitmapSource bitmapsource) 
{ 
    Bitmap bitmap; 
    using (MemoryStream outStream = new MemoryStream())  //Should I use "using" here? 
    { 
     BitmapEncoder enc = new BmpBitmapEncoder(); 
     enc.Frames.Add(BitmapFrame.Create(bitmapsource)); 
     enc.Save(outStream); 
     bitmap = new System.Drawing.Bitmap(outStream); 
    } 
    return bitmap; 
} 

Для белого изображения (255, 255, 255) я получаю 0 и 32 назад как 2 значения ...? Я не знаю, правильно ли это, и я просто интерпретирую их неправильно или если они просто совершенно неправы. (не правда больше с обновленным кодом)

EDIT: С обновленного кода я получаю 8192 для значения 255 и 1768 для значения 128. Это все еще не имеет большого смысла для меня ...

Мне также было интересно, если я должен использовать инструкцию «using» при загрузке изображения, потому что http://msdn.microsoft.com/en-us/library/z7ha67kw говорит, что мне нужно сохранить поток открытым на всю жизнь растровое изображение. Кажется, он отлично работает так, как сейчас, или это потому, что я копирую растровое изображение в другое растровое изображение, объявленное вне инструкции «using»?

ответ

2

Обычно форматы 64bpp будут иметь 16 бит для каждого из RGBA, поэтому вы действительно должны использовать ushort, а не byte. Например:

BitmapData bData1 = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat); 

byte* bData1Scan0Ptr = (byte*)bData1.Scan0.ToPointer(); 
byte* nextBase = bData1Scan0Ptr + bData1.Stride; 

for (int y = 0; y < bData1.Height; ++y) 
{ 
    ushort* pRow = (ushort*)bData1Scan0Ptr; 

    for (int x = 0; x < bData1.Width; ++x) 
    { 
     var red = pRow[2]; 
     var green = pRow[1]; 
     var blue = pRow[0]; 

     pRow += 4; 
    } 

    bData1Scan0Ptr = nextBase; 
    nextBase += bData1.Stride; 
} 

Возможно попробовать эту модификацию и комментарий с результатом, если это не решит проблему, то я буду обновлять мой ответ, если это необходимо.

+0

Спасибо! Я получаю разные результаты сейчас, но я все еще не уверен, что они верны. Мое изображение оранжевое (255,128,0), и значения, которые я получаю: красный: 8192, зеленый: 1768 и синий: 0 – VincentC

+1

I знаете, что это старый вопрос, но для тех, кто, как я, который наткнулся на это, 8192 - это максимальное значение (равное 255 для белого изображения 24bpp). –

Смежные вопросы