Exemple #1
0
/**
 @brief Blends two images based on alpha channel present in foreground image.
 @param foreground Foreground image, must have an alpha channel
 @param background Background image, may have an alpha channel
 @param blend_alpha Whether the returned image will have an alpha channel.
 @return A copy of the background image with the foreground image blended on
 top of it. The returned image will have an alpha channel iff the background
 image has an alpha channel. In that case the alpha channel is blended
 identical to the red/green/blue channels.
*/
wxImage BlendImage( const wxImage& foreground, const wxImage& background, bool blend_alpha )
{
    if ( ( foreground.GetWidth()  != background.GetWidth() ) || ( background.GetHeight() != foreground.GetHeight() ) )
    {
        wxLogDebugFunc(_T("size mismatch while blending"));
        return background;
    }

    bool zhu = blend_alpha && background.HasAlpha();
    if ( foreground.HasAlpha() )
    {
        wxImage ret( background.GetWidth(), foreground.GetHeight() );
        const unsigned char* background_data = background.GetData();
        const unsigned char* foreground_data = foreground.GetData();
        const unsigned char* background_alpha = NULL;
        const unsigned char* foreground_alpha = foreground.GetAlpha();
        unsigned char* result_data = ret.GetData();
        unsigned char* result_alpha = NULL;
        unsigned int pixel_count = background.GetWidth() * background.GetHeight();

        if ( zhu )
        {
          background_alpha = background.GetAlpha();
          ret.InitAlpha();
          result_alpha = ret.GetAlpha();
        }

        for ( unsigned int i = 0, i_a = 0; i < pixel_count * 3; i+=3,  i_a++ )
        {
            unsigned char fore_alpha = foreground_alpha[i_a] ;
            float back_blend_fac = ( 255 - fore_alpha)/255.0;
            float fore_blend_fac = fore_alpha/255.0 ;

            result_data[i]    = foreground_data[i]   * fore_blend_fac + background_data[i]   * back_blend_fac ;
            result_data[i+1]  = foreground_data[i+1] * fore_blend_fac + background_data[i+1] * back_blend_fac ;
            result_data[i+2]  = foreground_data[i+2] * fore_blend_fac + background_data[i+2] * back_blend_fac ;

            if ( zhu )
            {
              unsigned char back_alpha = background_alpha[i_a] ;
              result_alpha[i_a] = fore_alpha           * fore_blend_fac + back_alpha           * back_blend_fac ;
            }
        }
        return ret;
    }
    wxLogDebugFunc(_T("cannot blend without alpha"));
    return background;
}
void ImageDrawSelectionField(wxImage& img, int x, int y, int width, int height, unsigned char red, unsigned char green, unsigned char blue) {
	unsigned char* rawdata = img.GetData();
	unsigned char* rawalpha = img.GetAlpha();
	int thick = min(width,height)/100+1;
	int i,j,posx,posy;
	#define MACRO_SETPIXELCOLOR() \
		rawdata[3*(posx+posy)] = red; \
		rawdata[3*(posx+posy)+1] = green; \
		rawdata[3*(posx+posy)+2] = blue; \
		rawalpha[posx+posy] = 0xFF;
	width--;
	height--;
	for (i=0;i<=width;i++) {
		posx = (x+i)%img.GetWidth();
		for (j=0;j<thick;j++) {
			posy = ((y+j)%img.GetHeight())*img.GetWidth();
			MACRO_SETPIXELCOLOR()
			posy = ((y+height-j)%img.GetHeight())*img.GetWidth();
			MACRO_SETPIXELCOLOR()
		}
	}
	for (i=0;i<=height;i++) {
		posy = (y+i)%img.GetHeight()*img.GetWidth();
		for (j=0;j<thick;j++) {
			posx = (x+j)%img.GetWidth();
			MACRO_SETPIXELCOLOR()
			posx = (x+width-j)%img.GetWidth();
			MACRO_SETPIXELCOLOR()
		}
	}
}
Exemple #3
0
wxImage tintImage( wxImage to_colorize, wxColour col)
{
	wxImage highlightIcon(to_colorize.GetWidth(),to_colorize.GetHeight());
	bool do_alpha = false;
	if(to_colorize.HasAlpha())
	{
		highlightIcon.InitAlpha();
		do_alpha = true;
	}
	else if(to_colorize.HasMask())
	{
		highlightIcon.SetMaskFromImage(to_colorize,to_colorize.GetMaskRed(),to_colorize.GetMaskGreen(),to_colorize.GetMaskBlue());
	}
	for(int x = 0; x < highlightIcon.GetWidth(); x++)
	{
		for(int y = 0; y < highlightIcon.GetHeight(); y++)
		{
			to_colorize.GetData();
			unsigned char srcR = to_colorize.GetRed(x,y);
			unsigned char srcG = to_colorize.GetGreen(x,y);
			unsigned char srcB = to_colorize.GetBlue(x,y);
			highlightIcon.SetRGB(x,y,(srcR + col.Red())/2,(srcG + col.Green())/2, (srcB + col.Blue())/2);
			if(do_alpha)
				highlightIcon.SetAlpha(x,y,to_colorize.GetAlpha(x,y));
		}
	}
	return highlightIcon;
}
        void Surface::SetPixels( const wxImage& image )
        {
            m_Format = Format( image );
            size_t numPixels = (size_t)m_Format.m_Pitch*m_Format.m_CanvasHeight;
            if ( m_Format.GetDepth() == 24 ) {
                m_Pixels = (void*)new char[ numPixels ];
                memcpy( m_Pixels, image.GetData(), numPixels );
            } else if ( m_Format.GetDepth() == 32 ) {
                // wx uses a screwed up image format with a separate alpha plane. We need to convert into RGBA
                m_Pixels = (void*)new char[ numPixels ];
                unsigned int sPitch  = image.GetWidth()*3;
                unsigned char* pData = image.GetData();
                unsigned char* pAlpha= image.GetAlpha();
                unsigned int aMask = m_Format.m_AMask;
                unsigned int aShift= m_Format.m_AShift;
                int w = (int)m_Format.GetWidth();
                int h = (int)m_Format.GetHeight();
                for ( int y = 0; y < h; y++ ) {
                    unsigned int *pSrc  = (unsigned int*)(pData + y*sPitch);
                    unsigned int *pDst  = (unsigned int*)((unsigned char*)m_Pixels + y*m_Format.GetPitch());
                    for ( int x = 0; x < w; x++ ) {
                        *pDst++  = ((*pSrc) & ~aMask) | ((*pAlpha) << aShift);
                        pAlpha++; pSrc = (unsigned int *)(((unsigned char*)pSrc) + 3); // performance issues with odd addresses???
                    }
                }
            } else if ( m_Format.GetDepth() == 8 ) {
                // 8 bit gray scale - downscale to gray using luma

            } else if ( m_Format.GetDepth() == 1 ) {
                // 1 bit bitmap
            } else {
                // cannot compute
                m_Pixels = NULL;
            }
        }
/**
 * Predicate to check an image pixel matches color and alpha
 *
 * @param  aImage  the image to check
 * @param  aX      pixel x-coordinate
 * @param  aY      pixel y-coordinate
 * @param  aColor  expected color (alpha is 1.0 if image doesn't support alpha)
 * @return         true if colour match
 */
bool IsImagePixelOfColor( const wxImage& aImage, int aX, int aY, const KIGFX::COLOR4D& aColor )
{
    const wxSize imageSize = aImage.GetSize();

    if( imageSize.x < aX || imageSize.y < aY )
    {
        BOOST_TEST_INFO( "Pixel (" << aX << ", " << aY << "is not in image of size (" << imageSize.x
                                   << ", " << imageSize.y << ")" );
        return false;
    }

    const int r = aImage.GetRed( aX, aY );
    const int g = aImage.GetGreen( aX, aY );
    const int b = aImage.GetBlue( aX, aY );

    const int a = aImage.HasAlpha() ? aImage.GetAlpha( aX, aY ) : 255;

    if( !KI_TEST::IsColorNearHex( aColor, r, g, b, a ) )
    {
        BOOST_TEST_INFO( "Colour doesn't match: got rgba(" << r << ", " << g << ", " << b << ", "
                                                           << a << "), expected " << aColor );
        return false;
    }

    return true;
}
/// 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;
}
Exemple #7
0
void zen::convertToVanillaImage(wxImage& img)
{
    if (!img.HasAlpha())
    {
        const int width  = img.GetWidth ();
        const int height = img.GetHeight();
        if (width <= 0 || height <= 0) return;

        unsigned char mask_r = 0;
        unsigned char mask_g = 0;
        unsigned char mask_b = 0;
        const bool haveMask = img.HasMask() && img.GetOrFindMaskColour(&mask_r, &mask_g, &mask_b);
        //check for mask before calling wxImage::GetOrFindMaskColour() to skip needlessly searching for new mask color

        img.SetAlpha();
        ::memset(img.GetAlpha(), wxIMAGE_ALPHA_OPAQUE, width * height);

        //wxWidgets, as always, tries to be more clever than it really is and f***s up wxStaticBitmap if wxBitmap is fully opaque:
        img.GetAlpha()[width * height - 1] = 254;

        if (haveMask)
        {
            img.SetMask(false);
            unsigned char*       alphaPtr = img.GetAlpha();
            const unsigned char* dataPtr  = img.GetData();

            const int pixelCount = width * height;
            for (int i = 0; i < pixelCount; ++ i)
            {
                const unsigned char r = *dataPtr++;
                const unsigned char g = *dataPtr++;
                const unsigned char b = *dataPtr++;

                if (r == mask_r &&
                    g == mask_g &&
                    b == mask_b)
                    alphaPtr[i] = wxIMAGE_ALPHA_TRANSPARENT;
            }
        }
    }
    else
    {
        assert(!img.HasMask());
    }
}
Exemple #8
0
bool check_equal(const wxImage &self, const wxImage &cother)
{
	if(self.GetHeight() != cother.GetHeight()){
		return false;
	}
	if(self.GetWidth() != cother.GetWidth()) {
		return false;
	}
	if(strcmp((char*)self.GetData(), (char*)cother.GetData()) != 0){
		return false;
	}
	if(self.HasAlpha()) {
		if(!cother.HasAlpha())
			return false;
		if(strcmp((char*)self.GetAlpha(), (char*)cother.GetAlpha()) != 0){
			return false;
		}
	} else {
		return !cother.HasAlpha();
	}

	return true;
}
wxSVGCanvasImageCairoData::wxSVGCanvasImageCairoData(wxImage image) {
	m_count = 1;
	
	int bw = image.GetWidth();
	int bh = image.GetHeight();
	m_buffer = new unsigned char[bw*bh*4];
	wxUint32* data = (wxUint32*) m_buffer;
	
	// Create a surface object and copy the bitmap pixel data to it
	unsigned char* srcPix = image.GetData();
	if (image.HasAlpha()) { // alpha 
		m_surface = cairo_image_surface_create_for_data(m_buffer, CAIRO_FORMAT_ARGB32, bw, bh, bw*4);
		unsigned char* srcAlpha = image.GetAlpha();
		for (int y = 0; y < bh; y++) {
			for (int x = 0; x < bw; x++) {
				// Each pixel in CAIRO_FORMAT_ARGB32 is a 32-bit quantity, with alpha in the upper 8 bits,
				// then red, then green, then blue. The 32-bit quantities are stored native-endian.
				// Pre-multiplied alpha is used.
				unsigned char alpha = srcAlpha != NULL ? (*srcAlpha) : 255;
				if (alpha == 0)
					*data = 0;
				else
					*data = (alpha << 24 | (srcPix[0] * alpha / 255) << 16 | (srcPix[1] * alpha / 255) << 8
							| (srcPix[2] * alpha / 255));
				data++;
				srcPix += 3;
				if (srcAlpha)
					srcAlpha++;
			}
		}
	} else { // no alpha
		m_surface = cairo_image_surface_create_for_data(m_buffer, CAIRO_FORMAT_RGB24, bw, bh, bw * 4);
		for (int y = 0; y < bh; y++) {
			for (int x = 0; x < bw; x++) {
				// Each pixel in CAIRO_FORMAT_RGB24 is a 32-bit quantity, with the upper 8 bits unused.
				// Red, Green, and Blue are stored in the remaining 24 bits in that order.
				// The 32-bit quantities are stored native-endian.
				*data = (srcPix[0] << 16 | srcPix[1] << 8 | srcPix[2]);
				data++;
				srcPix += 3;
			}
		}
	}
}
QImage wxQtConvertImage( const wxImage &image )
{
	bool hasAlpha = image.HasAlpha();
	bool hasMask = image.HasMask();
	wxSize size ( image.GetWidth(), image.GetHeight() );
	QImage qtImage( wxQtConvertSize( size ),
				   ( (hasAlpha || hasMask ) ? QImage::Format_ARGB32 : QImage::Format_RGB32 ) );

	unsigned char *data = image.GetData();
	unsigned char *alpha = hasAlpha ? image.GetAlpha() : NULL;
	QRgb colour;

	QRgb maskedColour;
	if ( hasMask )
	{
		unsigned char r, g, b;
		image.GetOrFindMaskColour( &r, &g, &b );
		maskedColour = ( r << 16 ) + ( g << 8 ) + b;
	}

	for (int y = 0; y < image.GetHeight(); y++)
	{
		for (int x = 0; x < image.GetWidth(); x++)
		{
			if (hasAlpha)
			{
				colour = alpha[0] << 24;
				alpha++;
			}
			else
				colour = 0;

			colour += (data[0] << 16) + (data[1] << 8) + data[2];

			if ( hasMask && colour != maskedColour )
				colour += 0xFF000000; // 255 << 24

			qtImage.setPixel(x, y, colour);

			data += 3;
		}
	}
	return qtImage;
}
Exemple #11
0
void GOrgueBitmap::ScaleBMP(wxImage& img, double scale, const wxRect& rect, GOrgueBitmap* background)
{
	if (background && img.HasAlpha())
	{
		wxBitmap bmp(img.GetWidth(), img.GetHeight());
		wxBitmap orig(img);
		wxMemoryDC dc;

		dc.SelectObject(bmp);
		dc.DrawBitmap(background->GetBitmap(), -rect.GetX(), -rect.GetY(), false);
		dc.DrawBitmap(orig, 0, 0, true);
		bmp.SetMask(orig.GetMask());
		wxImage img_result = bmp.ConvertToImage();
		img_result.InitAlpha();
		memcpy(img_result.GetAlpha(), img.GetAlpha(), img.GetWidth() * img.GetHeight());

		m_bmp = (wxBitmap)img_result.Scale(img.GetWidth() * scale, img.GetHeight() * scale, wxIMAGE_QUALITY_BICUBIC);
	}
	else
		m_bmp = (wxBitmap)img.Scale(img.GetWidth() * scale, img.GetHeight() * scale, wxIMAGE_QUALITY_BICUBIC);
	m_Scale = scale;
}
Exemple #12
0
void Map::AssignImgData(ImgData *imgdata, wxImage &img)
{
    if(imgdata == NULL) return;

    if(img.IsOk())
    {
        unsigned char *pixdata, *alphadata;
        int width, height;
        long datasize;

        if(!img.HasAlpha()) img.SetAlpha();
        width = img.GetWidth();
        height = img.GetHeight();
        pixdata = img.GetData();
        alphadata = img.GetAlpha();
        datasize = (long) 4  * width * height;

        (*imgdata).width = (long)width;
        (*imgdata).height = (long)height;
        (*imgdata).data = (unsigned char*)malloc(datasize);
        if((*imgdata).data == NULL) return;

        int pi = 0, ai = 0;
        for(int di = 0; di < datasize;)
        {
            (*imgdata).data[di++] = pixdata[pi++];
            (*imgdata).data[di++] = pixdata[pi++];
            (*imgdata).data[di++] = pixdata[pi++];
            (*imgdata).data[di++] = alphadata[ai++];
        }
    }
    else
    {
        (*imgdata).width = 0;
        (*imgdata).height = 0;
        (*imgdata).data = NULL;
    }
}
Exemple #13
0
void wxCursor::InitFromImage( const wxImage & image )
{
    const int w = image.GetWidth();
    const int h = image.GetHeight();
    const guchar* alpha = image.GetAlpha();
    const bool hasMask = image.HasMask();
    int hotSpotX = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X);
    int hotSpotY = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y);
    if (hotSpotX < 0 || hotSpotX > w) hotSpotX = 0;
    if (hotSpotY < 0 || hotSpotY > h) hotSpotY = 0;
    GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(image.GetData(), GDK_COLORSPACE_RGB, false, 8, w, h, w * 3, NULL, NULL);
    if (alpha || hasMask)
    {
        guchar r = 0, g = 0, b = 0;
        if (hasMask)
        {
            r = image.GetMaskRed();
            g = image.GetMaskGreen();
            b = image.GetMaskBlue();
        }
        GdkPixbuf* pixbuf0 = pixbuf;
        pixbuf = gdk_pixbuf_add_alpha(pixbuf, hasMask, r, g, b);
        g_object_unref(pixbuf0);
        if (alpha)
        {
            guchar* d = gdk_pixbuf_get_pixels(pixbuf);
            const int stride = gdk_pixbuf_get_rowstride(pixbuf);
            for (int j = 0; j < h; j++, d += stride)
                for (int i = 0; i < w; i++, alpha++)
                    if (d[4 * i + 3])
                        d[4 * i + 3] = *alpha;
        }
    }
    m_refData = new wxCursorRefData;
    M_CURSORDATA->m_cursor = gdk_cursor_new_from_pixbuf(gtk_widget_get_display(wxGetRootWindow()), pixbuf, hotSpotX, hotSpotY);
    g_object_unref(pixbuf);
}
Exemple #14
0
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;
}
Exemple #15
0
bool wxDIB::Create(const wxImage& image, PixelFormat pf)
{
    wxCHECK_MSG( image.IsOk(), 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
    const bool hasAlpha = image.HasAlpha();
    const int bpp = 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 = 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. Note that RGB components order is reversed in
        // Windows bitmaps compared to wxImage and is actually BGR.
        unsigned char *dst = dstLineStart;
        if ( alpha )
        {
            int x;

            switch ( pf )
            {
                case PixelFormat_PreMultiplied:
                    // Pre-multiply pixel values so that the DIB could be used
                    // with ::AlphaBlend().
                    for ( x = 0; x < w; x++ )
                    {
                        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;
                    }
                    break;

                case PixelFormat_NotPreMultiplied:
                    // Just copy pixel data without changing it.
                    for ( x = 0; x < w; x++ )
                    {
                        *dst++ = src[2];
                        *dst++ = src[1];
                        *dst++ = src[0];

                        *dst++ = *alpha++;
                        src += 3;
                    }
                    break;
            }

        }
        else // no alpha channel
        {
            for ( int x = 0; x < w; x++ )
            {
                *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;
}