Transparent PNG

  • Follow


I have searched all the articles and tried various things, but cant seem 
to get this to work.  I have a png in a picturebox.  Then I have another 
png that is transparent.  the background is a compass frame and the 
foreground is the compass rose.  I update the image like this:

   Bitmap b2 = Properties.Resources.pngRose;
   Graphics gpCompass = Graphics.FromImage(pbCompass.Image);
   gpCompass.DrawImage(b2, 0, 0,
	new Rectangle(0, 0, b2.Width, b2.Height),
	GraphicsUnit.Pixel );
   pbCompass.Refresh();

However it draws the rose with a solid white background.

So I thought maybe I need to load the png from a file, but I am not sure 
how to do this in the emulator?

So 2 questions:
1.  can this be done by embedding the resource?
2.  Where do I place the png in the file system of the project in order 
to get it onto the emulator?

Peter
0
Reply Peter 1/16/2010 5:01:20 PM

I should have noted this is CF, 3.5 targeting WinMo 6+
Peter

Peter Carlson wrote:
> I have searched all the articles and tried various things, but cant seem 
> to get this to work.  I have a png in a picturebox.  Then I have another 
> png that is transparent.  the background is a compass frame and the 
> foreground is the compass rose.  I update the image like this:
> 
>   Bitmap b2 = Properties.Resources.pngRose;
>   Graphics gpCompass = Graphics.FromImage(pbCompass.Image);
>   gpCompass.DrawImage(b2, 0, 0,
>     new Rectangle(0, 0, b2.Width, b2.Height),
>     GraphicsUnit.Pixel );
>   pbCompass.Refresh();
> 
> However it draws the rose with a solid white background.
> 
> So I thought maybe I need to load the png from a file, but I am not sure 
> how to do this in the emulator?
> 
> So 2 questions:
> 1.  can this be done by embedding the resource?
> 2.  Where do I place the png in the file system of the project in order 
> to get it onto the emulator?
> 
> Peter
0
Reply Peter 1/16/2010 5:05:43 PM


Peter Carlson wrote:
> I should have noted this is CF, 3.5 targeting WinMo 6+

You should post to a newsgroup or other forum specific to Compact 
Framework questions.

There is no practical difference between storing the PNG in a resource 
versus reading from a file.  So I'm sure that line of experimentation 
will be a dead-end.  But, it's entirely possible that CF doesn't support 
transparency in bitmaps at all.

Your code example is insufficient to know whether your problem is 
related to bad input, bad usage, or lack of feature support in CF.  But 
given the likelihood that you are running into a limitation of the CF, 
you need to post your question where people experienced with the CF will 
see it.

What I can tell you from the code you posted is that you are failing to 
properly dispose of the Graphics instance you're using for drawing.  I'm 
also not particularly fond of the technique you're using with respect to 
the PictureBox control, but that's less important.  You definitely need 
to remember to dispose disposable objects though (preferably with the 
"using" statement).

Pete
0
Reply Peter 1/16/2010 7:35:20 PM

Peter,

I will try and find a CF group to post to.
I am disposing of the resources, the snippet of code was simply to show
how I am loading the resource and putting it into the picturebox.

Thanks for responding
Peter

Peter Duniho wrote:
> Peter Carlson wrote:
>> I should have noted this is CF, 3.5 targeting WinMo 6+
> 
> You should post to a newsgroup or other forum specific to Compact 
> Framework questions.
> 
> There is no practical difference between storing the PNG in a resource 
> versus reading from a file.  So I'm sure that line of experimentation 
> will be a dead-end.  But, it's entirely possible that CF doesn't support 
> transparency in bitmaps at all.
> 
> Your code example is insufficient to know whether your problem is 
> related to bad input, bad usage, or lack of feature support in CF.  But 
> given the likelihood that you are running into a limitation of the CF, 
> you need to post your question where people experienced with the CF will 
> see it.
> 
> What I can tell you from the code you posted is that you are failing to 
> properly dispose of the Graphics instance you're using for drawing.  I'm 
> also not particularly fond of the technique you're using with respect to 
> the PictureBox control, but that's less important.  You definitely need 
> to remember to dispose disposable objects though (preferably with the 
> "using" statement).
> 
> Pete
0
Reply Peter 1/17/2010 3:36:50 AM

Peter Carlson wrote:
> Peter,
> 
> I will try and find a CF group to post to.
> I am disposing of the resources, the snippet of code was simply to show
> how I am loading the resource and putting it into the picturebox.

For what it's worth, I spent a few minutes with Google, and at least as 
of a few years ago, it appears CF does not support your desired approach 
in at least two ways:

   � .NET CF doesn't use GDI+ so doesn't support alpha blending
   � The unmanaged Windows Mobile API now supports alpha blending, but 
the .NET CF bitmap-loading code converts all loaded bitmaps to the 
display format, which doesn't have alpha and so you lose any alpha 
channel information loading bitmaps

Of course, I have no idea whether the current versions of Windows Mobile 
or .NET CF have improved things.  But it's a place to start.

My main source of information was from this message topic:
http://social.msdn.microsoft.com/Forums/en-US/vssmartdevicesvbcs/thread/5624c89d-0e57-4d3f-90c4-eabc676e05f1

�and two links from that message:
http://blogs.msdn.com/chrislorton/archive/2006/04/07/570649.aspx
http://johan.andersson.net/blog/2007/10/solution-for-transparent-images-on.html

(Though, the latter has a really awful, obnoxious Twitter widget in the 
nav bar that actually extends all the way across the browser window on 
both Safari and Firefox, and maybe other browsers too, so it's difficult 
to read and use the links contained within).

Pete
0
Reply Peter 1/17/2010 4:56:34 AM

On 1/17/2010 1:01 AM, Peter Carlson wrote:
> I have searched all the articles and tried various things, but cant seem
> to get this to work. I have a png in a picturebox. Then I have another
> png that is transparent. the background is a compass frame and the
> foreground is the compass rose. I update the image like this:
>
> Bitmap b2 = Properties.Resources.pngRose;
> Graphics gpCompass = Graphics.FromImage(pbCompass.Image);
> gpCompass.DrawImage(b2, 0, 0,
> new Rectangle(0, 0, b2.Width, b2.Height),
> GraphicsUnit.Pixel );
> pbCompass.Refresh();
>
> However it draws the rose with a solid white background.
>
> So I thought maybe I need to load the png from a file, but I am not sure
> how to do this in the emulator?
>
> So 2 questions:
> 1. can this be done by embedding the resource?
> 2. Where do I place the png in the file system of the project in order
> to get it onto the emulator?
>
> Peter

Hi Peter,

I had done a similar project before (as a hobby project) but the way I 
do it is not to have the png image as transparent. I just set the 
background color to any color that you will use it as a "transparent" 
color. My preference is Magenta (R:255,G:0,B:255). Then just use one of 
the DrawImage overloads that take ImageAttributes as it parameter.

Example:

private ImageAttributes imageAttrib;
private Bitmap compassRose;

// call this from your form constructor
private void LoadImage()
{
   pictureBox.Image = Properties.Resources.pngFrame;
   compassRose = Properties.Resources.pngRose;

   imageAttrib = new ImageAttributes();
   imageAttrib.SetColorKey(compassRose.GetPixel(0, 0), 
compassRose.GetPixel(0, 0));
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
   Graphics g = e.Graphics;
   g.DrawImage(compassRose,
     new Rectangle(0, 0, compassRose.Width, compassRose.Height),
     0, 0, compassRose.Width, compassRose.Height,
     GraphicsUnit.Pixel,
     imageAttrib);
}

Eventually, I abandoned the project because the CF doesn't suppport 
image transformation (you can't rotate the image to any degree you want, 
so either you have to manually draw the compass needle, or have a 360 
images but this will increase the executable size very much). I don't 
know whether it can be done through P/Invoke either.

You can also look at http://www.freewarepocketpc.net/ website. I believe 
there are a lot of compass applications that use CF and you can examine 
the source code through reflector (better ask the author's permission 
first).

Regards.
0
Reply kndg 1/18/2010 1:20:06 AM

kndg wrote:
> [...]
> Eventually, I abandoned the project because the CF doesn't suppport 
> image transformation (you can't rotate the image to any degree you want, 
> so either you have to manually draw the compass needle, or have a 360 
> images but this will increase the executable size very much). I don't 
> know whether it can be done through P/Invoke either.

Not sure if, after my suggestion that Peter check other forums, whether 
he's still following this.  But in case he is�

As far as dealing with the rotation issue goes, if the platform doesn't 
support arbitrarily rotated drawing, you still don't really need 360 
different images for a compass overlay.

For one, IMHO the precision of the compass is unlikely to be usable to 
the nearest degree anyway.  So you probably only need 180 or 120 
discrete positions for the needle.

Then, you also need at most a quarter that number because even without 
fancy API support, it's trivial to do 90 degree bitmap rotations.  So 
then you only need 30-45 images.

I would guess the images should be reasonably small saved as PNG.  But 
if size is still a problem at that point, there is also the point that 
the overlay probably doesn't need to be at full resolution.  So you can 
get an additional 75% reduction in size just by halving the number of 
pixels in each direction in the stored bitmap and then doing a trivial 
stretch when using it.

Finally, there is the option to abandon a bitmap-based solution 
altogether.  Instead, store the compass needle outline as vector data, 
which can be stored _much_ more efficiently than a bitmap, and use 
Graphics.FillPolygon() to draw the needle (the docs say this is 
supported on CF).

In fact, while bitmap rotation done properly can be a bit of a pain, 
it's trivial to rotate individual coordinates with matrix math.  So a 
vector-based compass needle only really needs a single copy of the basic 
coordinates.  The space savings would be so vast as compared to having 
individual bitmaps for even a single position for the compass needle, 
never mind the storage required for a bitmap-based solution that can 
achieve the same quality output as a vector-based solution, that you 
could easily afford to design a vector-based needle representation that 
involves multiple fills and/or outlines, to make it prettier as needed.

Pete
0
Reply Peter 1/18/2010 5:17:59 AM

On 1/18/2010 1:17 PM, Peter Duniho wrote:
> kndg wrote:
>> [...]
>> Eventually, I abandoned the project because the CF doesn't suppport
>> image transformation (you can't rotate the image to any degree you
>> want, so either you have to manually draw the compass needle, or have
>> a 360 images but this will increase the executable size very much). I
>> don't know whether it can be done through P/Invoke either.
>
> Not sure if, after my suggestion that Peter check other forums, whether
> he's still following this. But in case he is�
>
> As far as dealing with the rotation issue goes, if the platform doesn't
> support arbitrarily rotated drawing, you still don't really need 360
> different images for a compass overlay.
>
> For one, IMHO the precision of the compass is unlikely to be usable to
> the nearest degree anyway. So you probably only need 180 or 120 discrete
> positions for the needle.
>
> Then, you also need at most a quarter that number because even without
> fancy API support, it's trivial to do 90 degree bitmap rotations. So
> then you only need 30-45 images.
>
> I would guess the images should be reasonably small saved as PNG. But if
> size is still a problem at that point, there is also the point that the
> overlay probably doesn't need to be at full resolution. So you can get
> an additional 75% reduction in size just by halving the number of pixels
> in each direction in the stored bitmap and then doing a trivial stretch
> when using it.
>

Hi Pete,

Good thoughts!
I started the project when I saw a very cool compass application that 
bundled on iPhone so I though whether I could make the same on my WinMob 
device. Having a compass face(rose) save as png gives me about 50K bytes 
file. 30 images of this accumulates to 1.5M bytes which is IMO way too 
big for a smart device application. Having a image reduce to quarter 
resolution would reduce the size to about 375K bytes (which maybe 
acceptable) but I don't know whether stretching back the image would 
preserve the transparency (especially around the edge).

> Finally, there is the option to abandon a bitmap-based solution
> altogether. Instead, store the compass needle outline as vector data,
> which can be stored _much_ more efficiently than a bitmap, and use
> Graphics.FillPolygon() to draw the needle (the docs say this is
> supported on CF).
>
> In fact, while bitmap rotation done properly can be a bit of a pain,
> it's trivial to rotate individual coordinates with matrix math. So a
> vector-based compass needle only really needs a single copy of the basic
> coordinates. The space savings would be so vast as compared to having
> individual bitmaps for even a single position for the compass needle,
> never mind the storage required for a bitmap-based solution that can
> achieve the same quality output as a vector-based solution, that you
> could easily afford to design a vector-based needle representation that
> involves multiple fills and/or outlines, to make it prettier as needed.
>

Yes, at first I would go this way, but I would lost the cool-ness of the 
compass interface. I prefer having the compass face to rotate instead of 
the needle. That's why I abandoned the project.

I heard that on CF 4.0, they will be a subset of WPF included on the 
framework (though I don't remember where I got that info) and it would 
be very interesting if they support image rotation also...(maybe I could 
revive back my dead projects).

Regards.
0
Reply kndg 1/18/2010 6:50:10 AM

7 Replies
763 Views

(page loaded in 0.17 seconds)


Reply: