2010-07-27 12 views
6

Aquí está mi intento (GDI + fea y mezcla GDI ...)Gdiplus :: ¿Mapa de bits a matriz BYTE?

// ... 
BYTE    pixels[BMP_WIDTH * BMP_HEIGHT * BMP_BPP]; 
HBITMAP   hBitmap; 
Gdiplus::Bitmap cBitmap(BMP_WIDTH, BMP_HEIGHT, PixelFormat32bppRGB); 
Gdiplus::Graphics cGraphics(&cBitmap); 
Gdiplus::Pen  cPen(Gdiplus::Color(255, 255, 0, 0)); 

cGraphics.DrawRectangle(&cPen, 0, 0, cBitmap.GetWidth() - 1, cBitmap.GetHeight() - 1); 

// and here it get's real ugly, I'd like to change that... 
cBitmap.GetHBITMAP(Gdiplus::Color(255, 255, 255), &hBitmap); 
GetBitmapBits(hBitmap, sizeof(pixels), pixels); 
// ... 

Alguien me dijo que usara LockBits pero realmente no entendía cómo. Lo intenté, pero fallé, así que no voy a publicar ese intento también.

Respuesta

6

Puede usar Bitmap::LockBits para obtener acceso a una matriz sin procesar de datos. Here que podría leer acerca de cómo usar Bitmap::LockBits.

2

Ha intentado suministrar los bytes al crear el mapa de bits:

int width = BMP_WIDTH; 
int height = BMP_HEIGHT; 
int stride = 4 * width; 
BYTE bytes[stride * height]; 

Gdiplus::Bitmap cBitmap(width, height, stride, PixelFormat32bppRGB, bytes); 
+0

Este es un caso fácil, se debe prestar atención que 'stride% 4 == 0' en el caso general (no todos los 3 componentes RGB funcionan). – malat

2

Aquí es cómo lo haría utilizando GDIPlus Bitmap.LockBits método definido en la cabecera GdiPlusBitmap.h:

en cuenta que desde los mapas de bits por lo general se alinea DWORD es posible que desee descartar estos datos no utilizado que se necesitaba para la alineación, como se ha comentado malat correctamente ..

Gdiplus::BitmapData bitmapData; 
    Gdiplus::Rect rect(0, 0, bitmap.GetWidth(), bitmap.GetHeight()); 

    //get the bitmap data 
    if(Gdiplus::Ok == bitmap.LockBits(
         &rect, //A rectangle structure that specifies the portion of the Bitmap to lock. 
         Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeWrite, //ImageLockMode values that specifies the access level (read/write) for the Bitmap. 
         bitmap.GetPixelFormat(),// PixelFormat values that specifies the data format of the Bitmap. 
         &bitmapData //BitmapData that will contain the information about the lock operation. 
         )) 
    { 
     //get the lenght of the bitmap data in bytes 
     int len = bitmapData.Height * std::abs(bitmapData.Stride); 

     BYTE* buffer = new BYTE[len]; 
     memcpy(bitmapData.Scan0, buffer, len);//copy it to an array of BYTEs 

     //... 

     //cleanup 
     bitmap.UnlockBits(&bitmapData);   
     delete []buffer; 
    } 
+0

No, esto no funcionará, 'bitmapData.Stride' es diferente de' bitmapData.Width * sizeof (bitmapData.PixelFormat) ', ya que contiene también datos no utilizados. Esto requiere un bucle for para descartar datos no utilizados. – malat

3

El siguiente código obtiene todos los píxeles de una imagen:

#include <vector> 
using namespace std; 

    vector<vector<UINT>> get_pixels(const wchar_t * name, int &Width, int &Height) { 


    Bitmap* bitmap = new Bitmap(name); 
    Width = bitmap->GetWidth(); 
    Height = bitmap->GetHeight(); 

    BitmapData* bitmapData = new BitmapData; 

    Rect rect(0, 0, Width, Height); 

    bitmap->LockBits(&rect, ImageLockModeRead, PixelFormat32bppARGB , bitmapData); 


    UINT* pixels = (UINT*)bitmapData->Scan0; 


    vector<vector<UINT>> result_pixels(Width, vector<UINT>(Height)); 

    INT iStride =abs(bitmapData->Stride); 

    for (UINT col = 0; col < Width; ++col) 
     for (UINT row = 0; row < Height; ++row) 
     { 


      unsigned int curColor = pixels[row * iStride/4 + col]; 
      int b = curColor & 0xff; 
      int g = (curColor & 0xff00) >> 8; 
      int r = (curColor & 0xff0000) >> 16; 
      int a = (curColor & 0xff000000) >> 24; 




      result_pixels[col][row] = RGB(r, g, b); 

     } 


    bitmap->UnlockBits(bitmapData); 

    return result_pixels; 
} 
Cuestiones relacionadas