{"record":{"id":"7bb6db83018dea09","repo":"SubtitleEdit/subtitleedit","slug":"could-not-decode-image","errorCode":null,"errorMessage":"Could not decode image","messagePattern":"Could not decode image","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/ui/Logic/Ocr/GoogleLens/Helper.cs","lineNumber":18,"sourceCode":"﻿using SkiaSharp;\nusing System;\nusing System.IO;\nusing System.IO.Compression;\nusing System.Threading.Tasks;\n\nnamespace Nikse.SubtitleEdit.Logic.Ocr.GoogleLens;\n\ninternal class Helper\n{\n    public static async Task<byte[]> ResizeImageAsync(byte[] buffer, int maxWidth, int maxHeight)\n    {\n        using var inputStream = new MemoryStream(buffer);\n        using var original = SKBitmap.Decode(inputStream);\n        \n        if (original == null)\n        {\n            throw new InvalidOperationException(\"Could not decode image\");\n        }\n\n        // Calculate new dimensions maintaining aspect ratio\n        float ratioX = (float)maxWidth / original.Width;\n        float ratioY = (float)maxHeight / original.Height;\n        float ratio = Math.Min(ratioX, ratioY);\n        \n        int newWidth = (int)(original.Width * ratio);\n        int newHeight = (int)(original.Height * ratio);\n\n        using var resized = original.Resize(new SKImageInfo(newWidth, newHeight), new SKSamplingOptions(SKFilterMode.Linear, SKMipmapMode.Linear));\n        if (resized == null)\n        {\n            throw new InvalidOperationException(\"Could not resize image\");\n        }\n            \n        using var image = SKImage.FromBitmap(resized);\n        using var data = image.Encode(SKEncodedImageFormat.Jpeg, 90);","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Logic/Ocr/GoogleLens/Helper.cs#L1-L36","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nvar resized = await Helper.ResizeImageAsync(buffer, 1000, 1000);\n\n// after\nusing var test = SKBitmap.Decode(new MemoryStream(buffer));\nif (test == null) throw new InvalidDataException(\"Image cannot be decoded\");\nvar resized = await Helper.ResizeImageAsync(buffer, 1000, 1000);","handlingStrategy":"validation","validationCode":"using var probe = SKBitmap.Decode(new MemoryStream(buffer));\nif (probe == null) throw new InvalidDataException(\"Image cannot be decoded by SkiaSharp\");","typeGuard":"static bool IsDecodable(byte[] b) { using var bmp = SKBitmap.Decode(new MemoryStream(b)); return bmp != null; }","tryCatchPattern":"try { var resized = await Helper.ResizeImageAsync(buffer, 1000, 1000); }\ncatch (InvalidOperationException ex) when (ex.Message == \"Could not decode image\") { /* skip or re-export */ }","preventionTips":["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."],"tags":["google-lens","ocr","image","skiasharp","decode","resize"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}