flxzt/rnote · error
Make piet image in BitmapImage draw impl failed, Err
Error message
Make piet image in BitmapImage draw impl failed, Err: {e:?} What it means
During BitmapImage's piet draw, creating the piet Image from the raw PNG/JPEG pixel data (via PietContext::make_image with the stored width, height, and byte buffer) failed. This is a rendering-time failure: the embedded image bytes are invalid or incompatible with the piet/cairo backend, so the stroke cannot be rasterized onto the target surface.
Solutions
- Validate the embedded image bytes (decode with an image library) before/while loading the document and repair or drop broken strokes.
- Re-export or re-embed the image and re-save the document.
- Check that pixel_width/pixel_height match the data buffer length and expected format (piet_image_format).
- Update piet/cairo backend crates in case of a known make_image bug.
Example fix
// before
cx.make_image(w, h, &self.image.data, piet_image_format)?;
// after
let piet_image = cx.make_image(w, h, &self.image.data, piet_image_format)
.with_context(|| format!("bad bitmap image {}x{} ({} bytes)", w, h, self.image.data.len()))?; Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: sanity-check the embedded image before rendering
fn bitmap_image_renderable(img: &BitmapImage) -> bool {
!img.image.data.is_empty()
&& img.image.pixel_width > 0
&& img.image.pixel_height > 0
&& image::load_from_memory(&img.image.data).is_ok()
} Type guard
fn has_valid_bitmap_data(img: &BitmapImage) -> bool {
matches!(image::load_from_memory(&img.image.data), Ok(_))
} Try / catch
match stroke.draw(&mut cx) {
Ok(()) => {},
Err(e) => log::warn!("skipping unrenderable bitmap stroke: {e:#}"),
} Prevention
- Validate embedded image bytes on document load and drop/repair corrupt strokes early.
- Keep pixel dimensions consistent with the data buffer size when constructing BitmapImage.
- Checksum embedded images at save time to detect corruption from partial writes.
When it happens
Trigger: Rendering a BitmapImage stroke whose `image.data` bytes are corrupt, truncated, in an unexpected format, or whose pixel dimensions mismatch the buffer size; rendering after deserializing a document with a damaged embedded image; backend make_image limitations.
Common situations: Opening an .rnote document whose embedded PNG data was corrupted by a partial save/transfer; rendering to an unusual piet backend that rejects the image format; memory pressure producing truncated buffers.
Related errors
- finishing piet context failed, Err
- Building text layout failed, Err
- finishing piet context failed, Err
- on-conflict behaviour is still Ask after prompting the user.
- Failed to get file stem
AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08).
Data as JSON: /api/errors/ecf52c05fc3f4415.
Report an issue: GitHub.
Appendix: source
Thrown at crates/rnote-engine/src/strokes/bitmapimage.rs:64
fn update_geometry(&mut self) {}
}
impl Drawable for BitmapImage {
fn draw(&self, cx: &mut impl piet::RenderContext, _image_scale: f64) -> anyhow::Result<()> {
let piet_image_format = piet::ImageFormat::from(self.image.memory_format);
cx.save().map_err(|e| anyhow::anyhow!("{e:?}"))?;
cx.transform(self.rectangle.affine.to_kurbo());
let piet_image = cx
.make_image(
self.image.pixel_width as usize,
self.image.pixel_height as usize,
&self.image.data,
piet_image_format,
)
.map_err(|e| {
anyhow::anyhow!("Make piet image in BitmapImage draw impl failed, Err: {e:?}")
})?;
let dest_rect = self.rectangle.cuboid.local_aabb().to_kurbo_rect();
cx.draw_image(&piet_image, dest_rect, piet::InterpolationMode::Bilinear);
cx.restore().map_err(|e| anyhow::anyhow!("{e:?}"))?;
Ok(())
}
}
impl Shapeable for BitmapImage {
fn bounds(&self) -> Aabb {
self.rectangle.bounds()
}
fn hitboxes(&self) -> Vec<Aabb> {
vec![self.bounds()]
}
View on GitHub (pinned to bbc5354502)