wxBitmap BitmapFromRGBAImage(int width, int height, const unsigned char *pixelsImage) { int x, y; wxBitmap bmp(width, height, 32); wxAlphaPixelData pixData(bmp); wxAlphaPixelData::Iterator p(pixData); for (y=0; y<height; y++) { p.MoveTo(pixData, 0, y); for (x=0; x<width; x++) { unsigned char red = *pixelsImage++; unsigned char green = *pixelsImage++; unsigned char blue = *pixelsImage++; unsigned char alpha = *pixelsImage++; p.Red() = wxPy_premultiply(red, alpha); p.Green() = wxPy_premultiply(green, alpha); p.Blue() = wxPy_premultiply(blue, alpha); p.Alpha() = alpha; ++p; } } return bmp; }
void wxPyCopyBitmapFromBuffer(wxBitmap* bmp, buffer data, Py_ssize_t DATASIZE, wxBitmapBufferFormat format, int stride) { int height = bmp->GetHeight(); int width = bmp->GetWidth(); switch (format) { // A simple sequence of RGB bytes case wxBitmapBufferFormat_RGB: { if (DATASIZE < width * height * 3) { wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size."); return; } wxNativePixelData pixData(*bmp, wxPoint(0,0), wxSize(width, height)); if (! pixData) { wxPyErr_SetString(PyExc_RuntimeError, "Failed to gain raw access to bitmap data."); return; } wxNativePixelData::Iterator p(pixData); for (int y=0; y<height; y++) { wxNativePixelData::Iterator rowStart = p; for (int x=0; x<width; x++) { p.Red() = *(data++); p.Green() = *(data++); p.Blue() = *(data++); ++p; } p = rowStart; p.OffsetY(pixData, 1); } break; } // A simple sequence of RGBA bytes case wxBitmapBufferFormat_RGBA: { if (DATASIZE < width * height * 4) { wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size."); return; } wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width, height)); if (! pixData) { wxPyErr_SetString(PyExc_RuntimeError, "Failed to gain raw access to bitmap data."); return; } wxAlphaPixelData::Iterator p(pixData); for (int y=0; y<height; y++) { wxAlphaPixelData::Iterator rowStart = p; for (int x=0; x<width; x++) { byte a = data[3]; p.Red() = wxPy_premultiply(*(data++), a); p.Green() = wxPy_premultiply(*(data++), a); p.Blue() = wxPy_premultiply(*(data++), a); p.Alpha() = a; data++; ++p; } p = rowStart; p.OffsetY(pixData, 1); } break; } // A sequence of 32-bit values in native endian order, // where the alpha is in the upper 8 bits, then red, then // green, then blue. The stride is the distance in bytes // from the beginning of one row of the image data to the // beginning of the next row. This may not be the same as // width*4 if alignment or platform specific optimizations // have been utilized. // NOTE: This is normally used with Cairo, which seems to // already have the values premultiplied. Should we have // a way to optionally do it anyway? case wxBitmapBufferFormat_RGB32: case wxBitmapBufferFormat_ARGB32: { bool useAlpha = (format == wxBitmapBufferFormat_ARGB32); byte* rowStart = data; wxUint32* bufptr; wxUint32 value; if (stride == -1) stride = width * 4; if (DATASIZE < stride * height) { wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size."); return; } wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height)); if (! pixData) { wxPyErr_SetString(PyExc_RuntimeError, "Failed to gain raw access to bitmap data."); return; } wxAlphaPixelData::Iterator pix(pixData); for (int y=0; y<height; y++) { pix.MoveTo(pixData, 0, y); bufptr = (wxUint32*)rowStart; for (int x=0; x<width; x++) { value = *bufptr; pix.Alpha() = useAlpha ? (value >> 24) & 0xFF : 255; pix.Red() = (value >> 16) & 0xFF; pix.Green() = (value >> 8) & 0xFF; pix.Blue() = (value >> 0) & 0xFF; ++pix; ++bufptr; } rowStart += stride; } break; } } }
void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill, ColourAllocated outline, int alphaOutline, int /*flags*/) { #if wxUSE_GRAPHICS_CONTEXT wxGCDC dc(*(wxMemoryDC*)hdc); wxColour penColour(wxColourFromCAandAlpha(outline, alphaOutline)); wxColour brushColour(wxColourFromCAandAlpha(fill, alphaFill)); dc.SetPen(wxPen(penColour)); dc.SetBrush(wxBrush(brushColour)); dc.DrawRoundedRectangle(wxRectFromPRectangle(rc), cornerSize); return; #else #ifdef wxHAVE_RAW_BITMAP // TODO: do something with cornerSize wxUnusedVar(cornerSize); int x, y; wxRect r = wxRectFromPRectangle(rc); wxBitmap bmp(r.width, r.height, 32); wxAlphaPixelData pixData(bmp); pixData.UseAlpha(); // Set the fill pixels ColourDesired cdf(fill.AsLong()); int red = cdf.GetRed(); int green = cdf.GetGreen(); int blue = cdf.GetBlue(); wxAlphaPixelData::Iterator p(pixData); for (y=0; y<r.height; y++) { p.MoveTo(pixData, 0, y); for (x=0; x<r.width; x++) { p.Red() = wxPy_premultiply(red, alphaFill); p.Green() = wxPy_premultiply(green, alphaFill); p.Blue() = wxPy_premultiply(blue, alphaFill); p.Alpha() = alphaFill; ++p; } } // Set the outline pixels ColourDesired cdo(outline.AsLong()); red = cdo.GetRed(); green = cdo.GetGreen(); blue = cdo.GetBlue(); for (x=0; x<r.width; x++) { p.MoveTo(pixData, x, 0); p.Red() = wxPy_premultiply(red, alphaOutline); p.Green() = wxPy_premultiply(green, alphaOutline); p.Blue() = wxPy_premultiply(blue, alphaOutline); p.Alpha() = alphaOutline; p.MoveTo(pixData, x, r.height-1); p.Red() = wxPy_premultiply(red, alphaOutline); p.Green() = wxPy_premultiply(green, alphaOutline); p.Blue() = wxPy_premultiply(blue, alphaOutline); p.Alpha() = alphaOutline; } for (y=0; y<r.height; y++) { p.MoveTo(pixData, 0, y); p.Red() = wxPy_premultiply(red, alphaOutline); p.Green() = wxPy_premultiply(green, alphaOutline); p.Blue() = wxPy_premultiply(blue, alphaOutline); p.Alpha() = alphaOutline; p.MoveTo(pixData, r.width-1, y); p.Red() = wxPy_premultiply(red, alphaOutline); p.Green() = wxPy_premultiply(green, alphaOutline); p.Blue() = wxPy_premultiply(blue, alphaOutline); p.Alpha() = alphaOutline; } // Draw the bitmap hdc->DrawBitmap(bmp, r.x, r.y, true); #else wxUnusedVar(cornerSize); wxUnusedVar(alphaFill); wxUnusedVar(alphaOutline); RectangleDraw(rc, outline, fill); #endif #endif }