Skip to content

Image fails to decode when cacheWidth or ResizeImage derives a side of 0 for a very thin image #194668

Closed

Description

@YeungKC

Steps to reproduce

  1. Create a very thin PNG image, for example 4000x1 pixels.
  2. Show it with Image.memory(bytes, cacheWidth: 100), or resolve ResizeImage(MemoryImage(bytes), width: 100).
  3. Alternatively, use ResizeImage(MemoryImage(bytes), width: 100, policy: ResizeImagePolicy.fit).

The same occurs for a 1x4000 image with cacheHeight: 100 or ResizeImage(height: 100).

Expected results

The image decodes to 100x1 (or 1x100). A derived side is at least 1 pixel.

Actual results

The other side is derived as 100 ~/ 4000 = 0, and the decode fails:

  • cacheWidth or cacheHeight with one side (ResizeImagePolicy.exact), and ui.instantiateImageCodec(bytes, targetWidth: 100): Exception: Codec failed to produce an image. The engine log shows Could not resize to empty dimensions.
  • ResizeImagePolicy.fit (with or without allowUpscaling): in debug mode, the assertion height == null || height > 0 (or width == null || width > 0) in TargetImageSize fails. By reading the code, in release mode the 0 becomes null, instantiateCodec derives 0 again, and the decode fails with the same exception.

Code sample

Code sample
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart';

Future<Uint8List> createPng(int width, int height) async {
  final recorder = ui.PictureRecorder();
  ui.Canvas(recorder).drawRect(
    ui.Rect.fromLTWH(0, 0, width.toDouble(), height.toDouble()),
    ui.Paint()..color = const ui.Color(0xFF0000FF),
  );
  final ui.Image image = await recorder.endRecording().toImage(width, height);
  final ByteData? data = await image.toByteData(format: ui.ImageByteFormat.png);
  return data!.buffer.asUint8List();
}

Future<Size> resolveSize(ImageProvider provider) async {
  final completer = Completer<Size>();
  provider.resolve(ImageConfiguration.empty).addListener(
    ImageStreamListener(
      (ImageInfo info, bool _) => completer.complete(
        Size(info.image.width.toDouble(), info.image.height.toDouble()),
      ),
      onError: (Object error, StackTrace? _) => completer.completeError(error),
    ),
  );
  return completer.future;
}

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  test('exact, one side', () async {
    final image = MemoryImage(await createPng(4000, 1));
    // Fails: Exception: Codec failed to produce an image
    expect(await resolveSize(ResizeImage(image, width: 100)), const Size(100, 1));
  });

  test('fit', () async {
    final image = MemoryImage(await createPng(4000, 1));
    // Fails: assertion in TargetImageSize
    expect(
      await resolveSize(ResizeImage(image, width: 100, policy: ResizeImagePolicy.fit)),
      const Size(100, 1),
    );
  });
}

Run with flutter test.

Screenshots or Video

No response

Logs

Logs
image_decoder_skia.cc(39) Could not resize to empty dimensions.
Exception: Codec failed to produce an image, possibly due to invalid image data.

Flutter Doctor output

Doctor output
Flutter 3.47.7 (channel stable). Reproduced on macOS and on Linux.
The same code is on master.

Activity

  1. self-assigned this
    on Oct 18, 2026
  2. added a commit that references this issue on Oct 20, 2026
    0af6449
  3. added a commit that references this issue on Oct 29, 2026
    604efe3
  4. github-actions commented on Nov 3, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  5. locked as resolved and limited conversation to collaborators on Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions