Skip to content

Impeller engine: toImage() / capture produces truncated long screenshots (works fine on Skia) #207

@lzxyh0227

Description

@lzxyh0227

When using the Impeller rendering engine, capturing a long image via RenderRepaintBoundary.toImage() (or similar capture methods) results in the right or bottom part of the image being cut off.
The same code works perfectly under Skia, producing a complete image.

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

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

@OverRide
State createState() => _ScreenshotTestPageState();
}

class _ScreenshotTestPageState extends State {
final GlobalKey repaintKey = GlobalKey();

Future _capture() async {
final boundary =
repaintKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
final ui.Image image = await boundary.toImage(pixelRatio: 3.0);
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
print('Captured image: ${image.width}x${image.height}, bytes: ${byteData?.lengthInBytes}');
}

@OverRide
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Screenshot Test')),
body: SingleChildScrollView(
child: RepaintBoundary(
key: repaintKey,
child: Column(
children: List.generate(
100,
(i) => Container(
height: 100,
color: i.isEven ? Colors.blue : Colors.green,
child: Center(child: Text('Item $i')),
),
),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _capture,
child: const Icon(Icons.camera_alt),
),
);
}
}`
The captured image should always match the widget’s full render area, regardless of whether Impeller or Skia is used.

Actual Behavior
• Under Impeller, the captured image is truncated (partially missing).
• Under Skia, the same code produces a complete image.

It seems that Impeller may create a render target or offscreen framebuffer limited to the visible viewport size, rather than the full logical size of the widget being captured.
As a result, when the target exceeds the current screen bounds (e.g., long scrollable views), part of the rendered content is clipped or discarded during capture.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions