2010-07-27 6 views
6

Oto moja próba (brzydki GDI + i GDI mix ...)Gdiplus :: Mapa bitowa do tablicy 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); 
// ... 

Ktoś powiedział mi użyć LockBits ale ja naprawdę nie rozumiem, jak to zrobić. Próbowałem, ale nie udało mi się, więc nie zamierzam również opublikować tej próby.

Odpowiedz

6

Możesz użyć Bitmap::LockBits, aby uzyskać dostęp do surowej tablicy danych. Here można przeczytać o tym, jak korzystać z Bitmap::LockBits.

2

Czy próbowałeś dostarczanie bajtów podczas tworzenia mapy bitowej

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

Jest to łatwy przypadek, należy zwrócić uwagę, że 'krok% 4 == 0' w ogólnym przypadku (nie wszystkie 3 komponenty działa RGB). – malat

2

Oto jak byłoby to zrobić za pomocą Bitmap.LockBits metody zdefiniowane w nagłówku GdiPlusBitmap.h GDIPlus:

Zauważ, że ponieważ bitmap DWORD są zwykle wyrównane może chcesz odrzucić tę niewykorzystaną dane, które było potrzebne do wyrównania, a Malát poprawnie skomentował ..

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

Nie to nie zadziała, 'bitmapData.Stride' różni się od' bitmapData.Width * sizeof (bitmapData.PixelFormat) ', ponieważ zawiera również nieużywane dane. Wymaga to pętli for, aby odrzucić nieużywane dane. – malat

3

Poniższy kod pobiera wszystkie piksele obrazu:

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