2

I'm having issues trying to use a PNG image with a build action of 'Resource' with the map marker generation of GMap.NET, which expects type Bitmap.

I create a BitmapImage using the pack Uri, and then convert the BitmapImage to a Bitmap by using the code provided by Sascha Henning in their answer here: Converting BitmapImage to Bitmap and vice versa

The resulting code is as follows:

BitmapImage bmi = new BitmapImage(
    new Uri("pack://application:,,,/Images/MapMarker_JobComplete.png"));
System.Drawing.Bitmap markerBitmap = Helpers.BitmapImageToBitmap(bmi);
GMarkerGoogle marker = new GMarkerGoogle(jobLoc, markerBitmap);

Where Helpers.BitmapImageToBitmap() is:

 public static Bitmap BitmapImageToBitmap(BitmapImage bitmapSource)
 {
     using( MemoryStream outstream = new MemoryStream())
     {
         BitmapEncoder enc = new BmpBitmapEncoder();
         enc.Frames.Add(BitmapFrame.Create(bitmapSource));
         enc.Save(outstream);
         return new System.Drawing.Bitmap(outstream);
     }
 }

The above works, but the image is rendered with a black background instead of a transparent background. I can only assume that the conversion to a BitmapImage or from a BitmapImage to Bitmap is responsible.

I found a reference to needing to save PNG images to a lower depth, but with currently installed software (Affinity), I couldn't export with a bit depth of 16 as said, only PNG-8 (bit depth of 8; red background, presumaby due to reduced quality) or the standard PNG-24 (bit depth of 32; black background) PNG-24 PNG-8


Currently to get the desired results (transparency supported), I use the PNG with a build action of 'Content', with the following code:

System.Drawing.Image imgMarker = System.Drawing.Bitmap.FromFile(
    System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
        "Images/MapMarker_JobComplete.png"));
GMarkerGoogle marker = new GMarkerGoogle(jobLoc, (System.Drawing.Bitmap)imgMarker);

The above works fine, so Bitmap must support transparency, but this leaves me with the PNG files as content and I would prefer them embedded into the executable, as well as be able to use the pack Uri in XAML if/when needed.

It's clear that there's some knowledge that I'm missing or haven't been able to glean out, and there's quite a few topics about people wanting to preserve transparency, but with the end result of a BitmapImage and not a Bitmap like I require.

Stanlow
  • 23
  • 4
  • 1
    I am not sure, but i guess (based on your explanation) that BmpBitmapEncoder does not support (creating) 32bpp BMPs. Why don't you try using PngBitmapEncoder instead? –  Mar 05 '19 at 14:31
  • @elgonzo Now I feel completely stupid, that fixed it straight away. Note to self, investigate example code thoroughly for alternatives. How can I close this while giving you credit? – Stanlow Mar 05 '19 at 14:42
  • Well, i am also feeling a bit stupid ;-) because of not realizing that you could simply open the embedded PNG resource as stream and let System.Drawing.Bitmap load it directly without needing the stuff in BitmapImageToBitmap. See the answers by Josip Medved and Hallgrim to this question: https://stackoverflow.com/questions/1192054/load-image-from-resources-area-of-project-in-c-sharp –  Mar 05 '19 at 15:08
  • Would the above solutions using Reflection have more of a performance impact than using the Bitmap Encoder? We've had issues in the past with clients using the software and reporting slowness. – Stanlow Mar 06 '19 at 11:12
  • I don't know how much slower or how much faster one approach is compared to another. But would it really matter, regardless of how much faster or slower? How many hundreds of pictures as embedded resources do you want/need to load from to make any possible performance difference significant? If you believe there is or might be a performance issue, validate the correctness of your belief by profiling your code using both approaches... –  Mar 06 '19 at 11:18

1 Answers1

0

Copying user2819245's old comment here, as it was/is the answer:

I am not sure, but i guess (based on your explanation) that BmpBitmapEncoder does not support (creating) 32bpp BMPs. Why don't you try using PngBitmapEncoder instead?

Benjol
  • 63,995
  • 54
  • 186
  • 268