.Net Maui returns png header when expecting BMP


When I try to convert an image in .net maui using IImage the resulting bmp has png headers rather than BMP headers. How can I create a proper BMP file?

My code:

 IImage image = PlatformImage.FromStream(await results[0].OpenReadAsync(),Microsoft.Maui.Graphics.ImageFormat.Bmp);
 float imageHeight = image.Height;
 float imageWidth = image.Width;
 float ratio = imageWidth / imageHeight;

 image = image.Resize(320, 480, ResizeMode.Bleed, true);
// base64ImageString = image.AsBytes(Microsoft.Maui.Graphics.ImageFormat.Bmp, 1);
 byte[] imageData = image.ToPlatformImage().AsBytes(Microsoft.Maui.Graphics.ImageFormat.Bmp, 1);

enter image description here

This is the imagedata array. The byte values are for a PNG Header.

its .net 10, used with android, visual studio 2026.

2
Aug 16 at 4:35 PM
User AvatarDoctor J
#c##android#.net#maui#.net-10.0

Accepted Answer

According to OP in the discussion comment, we know that the .Net platform is on Android.

Let's remove some "noises" from the original code:

// this tells MAUI how to interpret the stream, in this case its BMP IImage image = PlatformImage.FromStream(await results[0].OpenReadAsync(),Microsoft.Maui.Graphics.ImageFormat.Bmp); // from now, image is internally just a 2 dimensional RGB array and has nothing to do with image format // resize the image, still not related to image format image = image.Resize(320, 480, ResizeMode.Bleed, true); // .AsBytes() ignores requested format if the encoder doesn't support it and fall back to default PNG format. // But why??? byte[] imageData = image.ToPlatformImage().AsBytes(Microsoft.Maui.Graphics.ImageFormat.Bmp, 1);

.AsBytes() is an extension method which works on any class which implements the IImage interface.

In Microsoft.Maui.Graphics.ImageExtensions static class it is defined as such:

public static byte[] AsBytes(this IImage target, ImageFormat format = ImageFormat.Png, float quality = 1) { if (target == null) return null; using (var stream = new MemoryStream()) { target.Save(stream, format, quality); return stream.ToArray(); } }

GitHub source code:

  • https://github.com/dotnet/Microsoft.Maui.Graphics/blob/main/src/Microsoft.Maui.Graphics/ImageExtensions.cs

So it is calling the actual class's .Save() member function, which class implements the interface IImage.

For Android platform, it is the class Microsoft.Maui.Graphics.Platform.PlatformImage from this source code:

  • https://github.com/dotnet/maui/blob/main/src/Graphics/src/Graphics/Platforms/Android/PlatformImage.cs

The member function is defined as such:

public void Save(Stream stream, ImageFormat format = ImageFormat.Png, float quality = 1) { if (quality < 0 || quality > 1) throw new ArgumentOutOfRangeException(nameof(quality), "quality must be in the range of 0..1"); switch (format) { case ImageFormat.Jpeg: _bitmap.Compress(Bitmap.CompressFormat.Jpeg, (int)(quality * 100), stream); break; default: _bitmap.Compress(Bitmap.CompressFormat.Png, 100, stream); break; } }

That means if the format parameter is not JPEG, it always falls back to PNG, including your specified BMP.

User AvatarTony Chu
Aug 16 at 6:13 PM
2