Skip to content

[Impeller][regression] image.toByteData fails to convert raster image to PNG. #148851

@delfme

Description

@delfme

Steps to reproduce

Run full sample code below.

Basically, when trying to take a widget screenshot with usual snippet, the image.toByteData fails. Issue occurs on iOS Impeller. No issue on iOS skia and on android. It is a regression coz we use this code inside our app and it has always worked since lately.

   final boundary = screenshotKey.currentContext?.findRenderObject() as RenderRepaintBoundary;
   var image = await boundary.toImage(pixelRatio: 3);
   var byteData = await image.toByteData(format: ImageByteFormat.png);

Expected results

No error.

Actual results

[ERROR:flutter/lib/ui/painting/image_encoding.cc(215)] Could not convert raster image to PNG.

Code sample

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

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      showPerformanceOverlay: true,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),

    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  final screenshotKey = GlobalKey();

  Future<Uint8List> takeScreenshot({
    int width = 350,
    int height = 350
  }) async {
    // Wait a bit so the tree is mounted
    await Future.delayed(const Duration(milliseconds: 20), () {});
    final boundary = screenshotKey.currentContext?.findRenderObject() as RenderRepaintBoundary;
    var image = await boundary.toImage(pixelRatio: 3);
    print('DBUG: image.toByteData fails on iOS');
    var byteData = await image.toByteData(format: ImageByteFormat.png);
    print('DBUG: This log is never printed on iOS');
    Uint8List pngBytes = byteData!.buffer.asUint8List();
    return pngBytes;
  }

  @override
  Widget build(BuildContext context) {
    takeScreenshot();
    return MaterialApp(
      title: 'Impeller Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Impeller Demo'),
        ),
        body: Center(
            child: RepaintBoundary(
              key: screenshotKey,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Expanded(
                      child: Container(
                          color: Colors.black45
                    )
                 ),
              ],
            ),
          ),
        )
      ),
    );
  }
}








Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[✓] Flutter (Channel master, 3.22.0-42.0.pre.6, on macOS 14.2.1 23C71 darwin-arm64, locale en-IT)
[!] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.1)

Metadata

Metadata

Assignees

Labels

P1High-priority issues at the top of the work liste: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.platform-iosiOS applications specificallyr: 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