2010-07-27 28 views
6

Đây là nỗ lực của tôi (xấu xí GDI + GDI kết hợp ...)Gdiplus :: Bitmap vào mảng 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); 
// ... 

Có người nói với tôi để sử dụng LockBits nhưng tôi thực sự không hiểu làm thế nào. Tôi đã thử nó, nhưng tôi thất bại vì vậy tôi sẽ không đăng nỗ lực đó, quá.

Trả lời

6

Bạn có thể sử dụng Bitmap::LockBits để truy cập vào một mảng dữ liệu thô. Here bạn có thể đọc về cách sử dụng Bitmap::LockBits.

2

Bạn đã cố gắng cung cấp các byte khi bạn tạo bitmap:

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

Đây là một trường hợp đáng chú ý là 'stride% 4 == 0' trong trường hợp chung (không phải tất cả 3 thành phần RGB hoạt động). – malat

2

Dưới đây là làm thế nào tôi sẽ làm điều đó bằng GDIPlus Bitmap.LockBits phương pháp quy định tại tiêu đề GdiPlusBitmap.h:

ý rằng kể từ bitmap thường là DWORD được căn chỉnh, bạn có thể muốn loại bỏ dữ liệu không được sử dụng này cần thiết cho căn chỉnh, vì malat đã nhận xét chính xác ..

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

Không có điều này sẽ không hoạt động, 'bitmapData.Stride' khác với' bitmapData.Width * sizeof (bitmapData.PixelFormat) ', vì nó cũng chứa dữ liệu không sử dụng. Điều này đòi hỏi một vòng lặp for để loại bỏ dữ liệu không sử dụng. – malat

3

Mã sau đây nhận tất cả các điểm ảnh của một bức ảnh:

#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; 
} 
Các vấn đề liên quan