bool wxBitmap::CreateFromImage(const wxImage& image, int depth) { UnRef(); wxCHECK_MSG( image.Ok(), FALSE, wxT("invalid image") ) wxCHECK_MSG( depth == -1 || depth == 1, FALSE, wxT("invalid bitmap depth") ) if (image.GetWidth() <= 0 || image.GetHeight() <= 0) return false; m_refData = new wxBitmapRefData(); if (depth == 1) { return CreateFromImageAsBitmap(image); } else { #ifdef __WXGTK20__ if (image.HasAlpha()) return CreateFromImageAsPixbuf(image); #endif return CreateFromImageAsPixmap(image); } }
void wxHtmlImageCell::SetImage(const wxImage& img) { #if !defined(__WXMSW__) || wxUSE_WXDIB if ( img.Ok() ) { delete m_bitmap; int ww, hh; ww = img.GetWidth(); hh = img.GetHeight(); if ( m_bmpW == wxDefaultCoord ) m_bmpW = ww; if ( m_bmpH == wxDefaultCoord ) m_bmpH = hh; // Only scale the bitmap at the rendering stage, // so we don't lose quality twice /* if ((m_bmpW != ww) || (m_bmpH != hh)) { wxImage img2 = img.Scale(m_bmpW, m_bmpH); m_bitmap = new wxBitmap(img2); } else */ m_bitmap = new wxBitmap(img); } #endif }
/// Gets a rectangle from within another image, INCLUDING the alpha channel /// \bug in wxWidgets, wxImage::GetSubImage should do this itself. wxImage GetSubImageWithAlpha( const wxImage & Src, const wxRect &rect ) { //First part of this code is lifted from wxImage::GetSubImage() source code. wxImage image; wxCHECK_MSG( Src.Ok(), image, wxT("invalid image") ); wxCHECK_MSG( (rect.GetLeft()>=0) && (rect.GetTop()>=0) && ( rect.GetRight()<=Src.GetWidth()) && (rect.GetBottom()<=Src.GetHeight()), image, wxT("invalid subimage size") ); int subwidth=rect.GetWidth(); const int subheight=rect.GetHeight(); image.Create( subwidth, subheight, false ); unsigned char *subdata = image.GetData(), *data=Src.GetData(); wxCHECK_MSG( subdata, image, wxT("unable to create image") ); // JKC: Quick hack - don't deal with masks - need to understand macro M_IMGDATA first. // if (Src.M_IMGDATA->m_hasMask) // image.SetMaskColour( Src.M_IMGDATA->m_maskRed, Src.M_IMGDATA->m_maskGreen, Src.M_IMGDATA->m_maskBlue ); int subleft=3*rect.GetLeft(); int width=3*Src.GetWidth(); subwidth*=3; data+=rect.GetTop()*width+subleft; for (long j = 0; j < subheight; ++j) { memcpy( subdata, data, subwidth); subdata+=subwidth; data+=width; } // OK, so we've copied the RGB data. // Now do the Alpha channel. wxASSERT( Src.HasAlpha() ); image.InitAlpha(); subleft/=3; width/=3; subwidth/=3; data =Src.GetAlpha(); subdata =image.GetAlpha(); data+=rect.GetTop()*width+subleft; for (long j = 0; j < subheight; ++j) { memcpy( subdata, data, subwidth); subdata+=subwidth; data+=width; } return image; }
bool wxCreateGreyedImage(const wxImage& in, wxImage& out) { #if wxUSE_IMAGE out = in.ConvertToGreyscale(); if ( out.Ok() ) return true; #endif // wxUSE_IMAGE return false; }
bool CFrameWnd::StretchDraw(wxDC &x_dc, wxImage &x_img, wxRect &x_rect) {_STT(); if ( !x_img.Ok() ) return FALSE; // The slow but portable way... wxImage cWxImage = x_img.Copy(); cWxImage.Rescale( x_rect.GetWidth(), x_rect.GetHeight() ); x_dc.DrawBitmap( cWxImage, x_rect.x, x_rect.y ); return TRUE; }
wxImage FreeImage_Rescale(wxImage src, wxInt32 dst_width, wxInt32 dst_height, FREE_IMAGE_FILTER filter) { wxImage dst; if ((src.Ok()) && (dst_width > 0) && (dst_height > 0)) { dst.Create(dst_width, dst_height); // select the filter CGenericFilter *pFilter = NULL; switch(filter) { case FILTER_BOX: pFilter = new CBoxFilter(); break; case FILTER_BICUBIC: pFilter = new CBicubicFilter(); break; case FILTER_BILINEAR: pFilter = new CBilinearFilter(); break; case FILTER_BSPLINE: pFilter = new CBSplineFilter(); break; case FILTER_CATMULLROM: pFilter = new CCatmullRomFilter(); break; case FILTER_LANCZOS3: pFilter = new CLanczos3Filter(); break; } CResizeEngine Engine(pFilter); // perform upsampling or downsampling unsigned char *pSrc = src.GetData(); unsigned char *pDst = dst.GetData(); wxInt32 src_width = src.GetWidth(); wxInt32 src_height = src.GetHeight(); Engine.Scale(pSrc, src_width, src_height, pDst, dst_width, dst_height); delete pFilter; } return dst; }
// Creates a surface that will use wxImage's pixel data (RGB only) static wxIDirectFBSurfacePtr CreateSurfaceForImage(const wxImage& image) { wxCHECK_MSG( image.Ok(), NULL, _T("invalid image") ); // FIXME_DFB: implement alpha handling by merging alpha buffer with RGB // into a temporary RGBA surface wxCHECK_MSG( !image.HasAlpha(), NULL, _T("alpha channel not supported") ); DFBSurfaceDescription desc; desc.flags = (DFBSurfaceDescriptionFlags) (DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_PREALLOCATED); desc.caps = DSCAPS_NONE; desc.width = image.GetWidth(); desc.height = image.GetHeight(); desc.pixelformat = DSPF_RGB24; desc.preallocated[0].data = image.GetData(); desc.preallocated[0].pitch = 3 * desc.width; return wxIDirectFB::Get()->CreateSurface(&desc); }
wxBitmap::wxBitmap(const wxImage& image, int depth) { wxCHECK_RET( image.Ok(), wxT("invalid image") ); // create surface in screen's format: if ( !Create(image.GetWidth(), image.GetHeight(), depth) ) return; // then copy the image to it: wxIDirectFBSurfacePtr src(CreateSurfaceForImage(image)); wxIDirectFBSurfacePtr dst = M_BITMAP->m_surface; if ( !dst->SetBlittingFlags(DSBLIT_NOFX) ) return; if ( !dst->Blit(src->GetRaw(), NULL, 0, 0) ) return; // FIXME: implement mask creation from image's mask (or alpha channel?) wxASSERT_MSG( !image.HasMask(), _T("image masks are ignored for now") ); }
/*static*/ void wxMemoryFSHandler::AddFile(const wxString& filename, const wxImage& image, wxBitmapType type) { if ( !CheckDoesntExist(filename) ) return; wxMemoryOutputStream mems; if ( image.Ok() && image.SaveFile(mems, type) ) { m_Hash[filename] = new wxMemoryFSFile ( mems, wxImage::FindHandler(type)->GetMimeType() ); } else { wxLogError(_("Failed to store image '%s' to memory VFS!"), filename); } }
bool wxDIB::Create(const wxImage& image) { wxCHECK_MSG( image.Ok(), false, wxT("invalid wxImage in wxDIB ctor") ); const int h = image.GetHeight(); const int w = image.GetWidth(); // if we have alpha channel, we need to create a 32bpp RGBA DIB, otherwise // a 24bpp RGB is sufficient m_hasAlpha = image.HasAlpha(); const int bpp = m_hasAlpha ? 32 : 24; if ( !Create(w, h, bpp) ) return false; // DIBs are stored in bottom to top order (see also the comment above in // Create()) so we need to copy bits line by line and starting from the end const int srcBytesPerLine = w * 3; const int dstBytesPerLine = GetLineSize(w, bpp); const unsigned char *src = image.GetData() + ((h - 1) * srcBytesPerLine); const unsigned char *alpha = m_hasAlpha ? image.GetAlpha() + (h - 1)*w : NULL; unsigned char *dstLineStart = (unsigned char *)m_data; for ( int y = 0; y < h; y++ ) { // copy one DIB line unsigned char *dst = dstLineStart; if ( alpha ) { for ( int x = 0; x < w; x++ ) { // RGB order is reversed, and we need to premultiply // all channels by alpha value for use with ::AlphaBlend. const unsigned char a = *alpha++; *dst++ = (unsigned char)((src[2] * a + 127) / 255); *dst++ = (unsigned char)((src[1] * a + 127) / 255); *dst++ = (unsigned char)((src[0] * a + 127) / 255); *dst++ = a; src += 3; } } else // no alpha channel { for ( int x = 0; x < w; x++ ) { // RGB order is reversed. *dst++ = src[2]; *dst++ = src[1]; *dst++ = src[0]; src += 3; } } // pass to the previous line in the image src -= 2*srcBytesPerLine; if ( alpha ) alpha -= 2*w; // and to the next one in the DIB dstLineStart += dstBytesPerLine; } return true; }