GetPixel (+ alpha) for a wxBitmap

If you have a cool piece of software to share, but you are not hosting it officially yet, please dump it in here. If you have code snippets that are useful, please donate!
Post Reply
shambles
In need of some credit
In need of some credit
Posts: 4
Joined: Mon Dec 31, 2007 3:52 am

GetPixel (+ alpha) for a wxBitmap

Post by shambles » Mon Dec 31, 2007 3:59 am

I was struggling writing a GetPixel function for a wxBitmap object. The issue is that (on windows platforms at least) the "::GetPixel" system function does NOT handle alpha - so I was getting incorrect colours (which was breaking one of my font rendering systems).

I was originally using wxDC (memory DCs) - but have now rewritten it to work like this (actually very simple) - if someone has a better solution, I'd love to see it!
(not sure if it counts as a bug, but a note in the manual for the GetPixel wxDC function, to say that it doesn't support alpha might be useful!).

...

Code: Select all

Colour Image::GetPixelColour(const Vec2D & pt)
{
	wxBitmap temp;
	wxImage img;
	Colour c;

	temp = m_image.GetSubBitmap(wxRect(pt.x, pt.y, 1, 1));
	img = temp.ConvertToImage();

	c.Set(img.GetRed(0,0), img.GetGreen(0,0), img.GetBlue(0,0), img.GetAlpha(0,0));

	return c;
}
(note that Colour & Vec2D are my own internal functions - can be easily substituted for the wx equivs).

- Mike

shambles
In need of some credit
In need of some credit
Posts: 4
Joined: Mon Dec 31, 2007 3:52 am

Drawing into a 32bit (RGBA) wxImage

Post by shambles » Wed Jan 02, 2008 5:03 am

Had similar problems when trying to draw into my 32bit wxBitmap. Selecting it into a wxMemoryDC doesn't work - pens don't support alpha, and drawing with a "solid" colour only made a transparent line appear.

So decided to do it manually - see the following code. Not sure if it works on non-Windows platforms though.

...

Code: Select all

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~ Draw a line between 2 pts, in the given colour. Also draws/fills in
 ~ the final coordinate.
 ~
 */

void Image::DrawLine(const Vec2D & start_pt, const Vec2D & end_pt, const Colour & new_col)
{
	int i;
	int l;

	l = max((abs(end_pt.x - start_pt.x))+1, (abs(end_pt.y - start_pt.y))+1);

	for (i=0; i<=l; i++)
	{
		DrawPoint(Vec2D(start_pt.x + ((end_pt.x - start_pt.x)*i)/l, start_pt.y + ((end_pt.y - start_pt.y)*i)/l), new_col);
	}
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~ Draw a single pixel, in the given colour.
 ~
 */

void Image::DrawPoint(const Vec2D & pt, const Colour & col)
{
	u32 * d;

	if ((pt.x < 0) || (pt.x >= GetWidth()))
	{
		return;
	}

	if ((pt.y < 0) || (pt.y >= GetHeight()))
	{
		return;
	}

	wxAlphaPixelData pixeldata(m_image);
    wxAlphaPixelData::Iterator p(pixeldata);

	p.MoveTo(pixeldata, pt.x, pt.y);

	p.Red() = col.GetRed();
	p.Green() = col.GetGreen();
	p.Blue() = col.GetBlue();
	p.Alpha() = col.GetAlpha();
}

Post Reply