Description
Steps to reproduce
Starting with Flutter version 3.32.1, we’ve encountered rendering issues when using the toImage() method from a RenderRepaintBoundary. These issues manifest as various visual artifacts or glitches in the exported images. This did not occur in version 3.29.x, where image exports worked as expected.
The problem is especially evident in two scenarios:
1. Exporting normal UI elements — certain images consistently display distorted output
2. Exporting widgets with transparency and shadows — for instance, a Container with a black background at 25% opacity and a subtle shadow results in corrupted or visually glitched outputs. These artifacts seem to appear in the transparent/shadow areas.
Steps to Reproduce:
1. Create a widget wrapped in a RepaintBoundary.
2. Call toImage() and export the result as a PNG (e.g., via toByteData()).
3. Run this on Flutter 3.32.1.
4. Compare the exported image with the rendered widget in-app.
Expected results
The exported image should accurately reflect the widget’s appearance, including correct transparency and shadow rendering, as was the case in 3.29.x.
Actual results
- Exported images may contain glitches, noise, or unintended patterns.
- Transparent elements with shadows often render incorrectly or with visual artifacts.
Code sample
Code sample
class StoryExportUtil {
/// Export a rendered widget to an image file
/// Returns the path to the exported image file
Future<String?> exportWidgetToImage(
RenderRepaintBoundary boundary,
) async {
try {
// Capture the widget as an image with a high pixel ratio for better quality
final ui.Image image = await boundary.toImage(pixelRatio: 4.0);
// Compress as PNG for best quality
final ByteData? byteData = await image.toByteData(
format: ui.ImageByteFormat.png,
);
if (byteData == null) {
throw Exception('Failed to get image data');
}
final Uint8List pngBytes = byteData.buffer.asUint8List();
// Save the image to a temporary file
final directory = await getTemporaryDirectory();
final timestamp = DateTime.now().millisecondsSinceEpoch;
final path = '${directory.path}/workout_story_$timestamp.png';
final File imageFile = File(path);
await imageFile.writeAsBytes(pngBytes);
return path;
} catch (e) {
debugPrint('Error exporting story to image: $e');
return null;
}
}
}
Screenshots or Video
Logs
Logs
[Paste your logs here]
Flutter Doctor output
Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.32.1, on macOS 15.5 24F74 darwin-arm64, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0-rc4)
[✓] Xcode - develop for iOS and macOS (Xcode 16.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.3)
[✓] VS Code (version 1.100.2)
[✓] Connected device (3 available)
[✓] Network resources
• No issues found!