SubtitleEdit/subtitleedit · error · InvalidOperationException
Could not decode image
Error message
Could not decode image
What it means
Thrown by Helper.ResizeImageAsync when SKBitmap.Decode returns null for the input buffer. A null bitmap means SkiaSharp could not decode the bytes into a raster — the data is not a supported/valid image, or the native codec for that format is missing. This fires during the downscale step used to fit images into Lens's 1000x1000 limit.
Source
Thrown at src/ui/Logic/Ocr/GoogleLens/Helper.cs:18
using SkiaSharp;
using System;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
namespace Nikse.SubtitleEdit.Logic.Ocr.GoogleLens;
internal class Helper
{
public static async Task<byte[]> ResizeImageAsync(byte[] buffer, int maxWidth, int maxHeight)
{
using var inputStream = new MemoryStream(buffer);
using var original = SKBitmap.Decode(inputStream);
if (original == null)
{
throw new InvalidOperationException("Could not decode image");
}
// Calculate new dimensions maintaining aspect ratio
float ratioX = (float)maxWidth / original.Width;
float ratioY = (float)maxHeight / original.Height;
float ratio = Math.Min(ratioX, ratioY);
int newWidth = (int)(original.Width * ratio);
int newHeight = (int)(original.Height * ratio);
using var resized = original.Resize(new SKImageInfo(newWidth, newHeight), new SKSamplingOptions(SKFilterMode.Linear, SKMipmapMode.Linear));
if (resized == null)
{
throw new InvalidOperationException("Could not resize image");
}
using var image = SKImage.FromBitmap(resized);
using var data = image.Encode(SKEncodedImageFormat.Jpeg, 90);View on GitHub (pinned to 17a9f07487)
Solutions
- Validate/decode the image upstream (SKBitmap.Decode) and skip OCR if null.
- Re-export the image as standard sRGB PNG/JPEG.
- Ensure SkiaSharp native assets match the runtime/OS.
- Catch InvalidOperationException and fall back to the original bytes or skip resize.
Example fix
// before
var resized = await Helper.ResizeImageAsync(buffer, 1000, 1000);
// after
using var test = SKBitmap.Decode(new MemoryStream(buffer));
if (test == null) throw new InvalidDataException("Image cannot be decoded");
var resized = await Helper.ResizeImageAsync(buffer, 1000, 1000); Defensive patterns
Strategy: validation
Validate before calling
using var probe = SKBitmap.Decode(new MemoryStream(buffer));
if (probe == null) throw new InvalidDataException("Image cannot be decoded by SkiaSharp"); Type guard
static bool IsDecodable(byte[] b) { using var bmp = SKBitmap.Decode(new MemoryStream(b)); return bmp != null; } Try / catch
try { var resized = await Helper.ResizeImageAsync(buffer, 1000, 1000); }
catch (InvalidOperationException ex) when (ex.Message == "Could not decode image") { /* skip or re-export */ } Prevention
- Pre-decode the image to confirm it is valid before resizing.
- Re-export non-standard colorspaces (CMYK) to sRGB.
- Ensure SkiaSharp native binaries match the runtime.
- Reject truncated/empty buffers upstream.
When it happens
Trigger: ResizeImageAsync is called with a corrupt, truncated, or unsupported-format byte array (the earlier SKCodec.Create may have succeeded but full decode fails, or the path was reached with a different buffer).
Common situations: A partially downloaded image; a format whose codec is absent in the deployed SkiaSharp native binaries; a CMYK JPEG or exotic colorspace SkiaSharp refuses; a zero-length buffer.
Related errors
- Could not resize image
- File type not supported
- Could not determine image dimensions
- Image dimensions are larger than 1000x1000
- Could not determine original image dimensions.
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/7bb6db83018dea09.
Report an issue: GitHub.