Skip to content

[Impeller] Render bug canvas.drawImageRect when src param is bigger than image #157167

@rokarnus

Description

@rokarnus

Steps to reproduce

Download a jpg image and put it in pubspec.yaml as an asset. This sample uses free image from https://www.pexels.com/photo/clear-glass-cup-filled-with-chocolate-cream-1684880/ in Medium size.

Then run the code sample with and without impeller. When the "Rect src" parameter for canvas.drawImageRect is bigger than the actual image a stretched image bug appears with impeller. But not with Skia.

The screenshots are from Android. The same happens on iOS.

Expected results

Should draw the image without "stretched" render bug.
Screenshot_20241018-175002

Actual results

Draws the image with "stretched" render bug.
Screenshot_20241018-174935

Code sample

Code sample
import 'dart:async';

import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'package:flutter/services.dart';

void main() {
  runApp(const MainApp());
}

class MainApp extends StatefulWidget {
  const MainApp({super.key});

  @override
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  ui.Image? loadedImage;

  @override
  void initState() {
    super.initState();

    //load image
    _loadImage();
  }

  Future<void> _loadImage() async {
    String imagePath = 'assets/chocolate-cream.jpg';
    loadedImage = await _loadImageFromAssets(imagePath);
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: _getBody(),
      ),
    );
  }

  Widget _getBody() {
    if (loadedImage == null) {
      return const Center(
        child: Text('Loading ...'),
      );
    } else {
      return CustomPaint(
        painter: MyCustomPainter(loadedImage: loadedImage!),
        child: Container(),
      );
    }
  }
}

class MyCustomPainter extends CustomPainter {
  final ui.Image loadedImage;

  MyCustomPainter({super.repaint, required this.loadedImage});

  @override
  void paint(Canvas canvas, Size size) {
    //get the center of the screen
    ui.Offset centerOffset = Offset(size.width / 2.0, size.height / 2.0);

    //store original imageSize
    Size imageSize =
        Size(loadedImage.width.toDouble(), loadedImage.height.toDouble());

    //The Rect src is intentionally bigger than image dimensions.
    //This causes the render bug on impeller.
    Rect src =
        Rect.fromLTWH(0, 0, imageSize.width * 1.3, imageSize.height * 1.3);

    //this 200x200 rect should fit on most screens.
    Rect dst = Rect.fromCenter(center: centerOffset, width: 200, height: 200);

    canvas.drawImageRect(loadedImage, src, dst, Paint());
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

Future<ui.Image?> _loadImageFromAssets(String path) async {
  try {
    final ByteData data = await rootBundle.load(path);

    final List<int> bytes = data.buffer.asUint8List();
    final Completer<ui.Image> completer = Completer();
    ui.decodeImageFromList(Uint8List.fromList(bytes), (image) {
      completer.complete(image);
    });

    return completer.future;
  } catch (e) {
    // If asset loading fails, return null
    return null;
  }
}

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.24.3, on Microsoft Windows [Version 10.0.22631.4317], locale en-SI)
    • Flutter version 3.24.3 on channel stable at C:\Users\Rok\Flutter SDK\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 2663184aa7 (5 weeks ago), 2024-09-11 16:27:48 -0500
    • Engine revision 36335019a8
    • Dart version 3.5.3
    • DevTools version 2.37.3

[✓] Windows Version (Installed version of Windows is version 10 or higher)

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at C:\Users\Rok\AppData\Local\Android\sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java
    • Java version OpenJDK Runtime Environment (build 21.0.3+-12282718-b509.11)
    • All Android licenses accepted.

[✓] Chrome - develop for the web
    • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe

[✗] Visual Studio - develop Windows apps
    ✗ Visual Studio not installed; this is necessary to develop Windows apps.
      Download at https://visualstudio.microsoft.com/downloads/.
      Please install the "Desktop development with C++" workload, including all of its default components

[✓] Android Studio (version 2024.2)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 21.0.3+-12282718-b509.11)

[✓] VS Code (version 1.94.2)
    • VS Code at C:\Users\Rok\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.98.0

[✓] Connected device (4 available)
    • Pixel 8 (mobile)  • 37261FDJH00C99 • android-arm64  • Android 14 (API 34)
    • Windows (desktop) • windows        • windows-x64    • Microsoft Windows [Version 10.0.22631.4317]
    • Chrome (web)      • chrome         • web-javascript • Google Chrome 129.0.6668.103
    • Edge (web)        • edge           • web-javascript • Microsoft Edge 125.0.2535.85

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 1 category.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: imagesLoading, displaying, rendering imagese: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.found in release: 3.24Found to occur in 3.24found in release: 3.27Found to occur in 3.27has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionteam-engineOwned by Engine teamtriaged-engineTriaged by Engine team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions