dotnet/machinelearning · error · InvalidOperationException

Image pixel format is not supported

Error message

Image pixel format is not supported

What it means

ImagePixelExtractor converts an already-decoded image's raw pixels into channel planes. It only knows how to index bytes for Bgra32 and Rgba32 pixel formats; any other MLPixelFormat falls through the switch's discard arm and raises an InvalidOperationException because the byte offsets for alpha/red/green/blue are undefined for that format.

Source

Thrown at src/Microsoft.ML.ImageAnalytics/ImagePixelExtractor.cs:370

                        float offset = ex.OffsetImage;
                        float scale = ex.ScaleImage;
                        Contracts.Assert(scale != 0);

                        // REVIEW: split the getter into 2 specialized getters, one for float case and one for byte case.
                        Span<float> vf = typeof(TValue) == typeof(float) ? MemoryMarshal.Cast<TValue, float>(editor.Values) : default;
                        Span<byte> vb = typeof(TValue) == typeof(byte) ? MemoryMarshal.Cast<TValue, byte>(editor.Values) : default;
                        Contracts.Assert(!vf.IsEmpty || !vb.IsEmpty);
                        bool needScale = offset != 0 || scale != 1;
                        Contracts.Assert(!needScale || !vf.IsEmpty);

                        ImagePixelExtractingEstimator.GetOrder(ex.OrderOfExtraction, ex.ColorsToExtract, out int a, out int r, out int b, out int g);

                        ReadOnlySpan<byte> pixelData = src.Pixels;
                        (int alphaIndex, int redIndex, int greenIndex, int blueIndex) = src.PixelFormat switch
                        {
                            MLPixelFormat.Bgra32 => (3, 2, 1, 0),
                            MLPixelFormat.Rgba32 => (3, 0, 1, 2),
                            _ => throw new InvalidOperationException($"Image pixel format is not supported")
                        };

                        int h = height;
                        int w = width;
                        int pixelByteCount = alphaIndex > 0 ? 4 : 3;
                        int ix = 0;

                        if (ex.InterleavePixelColors)
                        {
                            int idst = 0;
                            for (int y = 0; y < h; ++y)
                            {
                                for (int x = 0; x < w; x++)
                                {
                                    if (!vb.IsEmpty)
                                    {
                                        if (a != -1) { vb[idst + a] = (byte)(alphaIndex > 0 ? pixelData[ix + alphaIndex] : 255); }
                                        if (r != -1) { vb[idst + r] = pixelData[ix + redIndex]; }

View on GitHub (pinned to 7b76e69cf9)

Solutions

  1. Convert the image to Rgba32 or Bgra32 before extraction (e.g. re-encode/decode via SKBitmap with SKColorType.Bgra8888)
  2. Check src.PixelFormat ahead of the pipeline and normalize all inputs to a supported 32bpp format at load time
  3. Upgrade ML.NET / Microsoft.ML.ImageAnalytics — newer versions may support additional formats

Example fix

// before
var img = MLImage.CreateFromFile(path); // may be Grayscale8 etc.
// after
var img = MLImage.CreateFromFile(path);
if (img.PixelFormat != MLPixelFormat.Bgra32 && img.PixelFormat != MLPixelFormat.Rgba32)
    img = ConvertToBgra32(img); // re-encode via SkiaSharp to SKColorType.Bgra8888
Defensive patterns

Strategy: type-guard

Validate before calling

if (img.PixelFormat != MLPixelFormat.Bgra32 && img.PixelFormat != MLPixelFormat.Rgba32)
    img = ConvertToBgra32(img);

Type guard

bool IsSupportedPixelFormat(MLPixelFormat fmt) => fmt is MLPixelFormat.Bgra32 or MLPixelFormat.Rgba32;

Try / catch

try
{
    ExtractPixels(img);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("pixel format"))
{
    img = ConvertToBgra32(img);
    ExtractPixels(img);
}

Prevention

When it happens

Trigger: A decoded MLImage/Image whose PixelFormat is neither MLPixelFormat.Bgra32 nor MLPixelFormat.Rgba32 (e.g. Grayscale8, Bgr24, indexed formats) flowing into the pixel extraction stage of an image-processing pipeline.

Common situations: Loading grayscale or palette images (PNG-8, 16-bit PNG, JPEG gray) from disk or a custom decoder, or images produced by another component that returns a non-32bpp format.

Related errors


AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11). Data as JSON: /api/errors/2e95bbefd5862dc4. Report an issue: GitHub.