-
Notifications
You must be signed in to change notification settings - Fork 96
Description
I'm trying to replicate the results of the example file in piet-coregraphics. I'm unable to render an empty PNG file.
use eyre::{Context, Result};
use piet::kurbo::Size;
use std::fs::File;
use std::io::BufWriter;
use core_graphics::color_space::CGColorSpace;
use core_graphics::context::CGContext;
use piet::{Color, RenderContext};
use piet_coregraphics::CoreGraphicsContext;
fn main() -> Result<()> {
let size = Size {
width: 1.0,
height: 1.0,
};
let mut cg_ctx = make_cg_ctx(size);
let mut piet_context = CoreGraphicsContext::new_y_up(&mut cg_ctx, size.height, None);
draw(&mut piet_context).wrap_err("failed to draw file")?;
piet_context
.finish()
.map_err(|e| eyre::eyre!("{}", e))
.wrap_err("failed to finalize piet context")?;
std::mem::drop(piet_context);
let mut data = cg_ctx.data();
let file = File::create("out.png").wrap_err("failed to create output file")?;
let w = BufWriter::new(file);
dbg!(data.len());
let mut encoder = png::Encoder::new(w, dbg!(size.width as u32), dbg!(size.height as u32));
encoder.set_color(png::ColorType::Rgba);
encoder.set_depth(png::BitDepth::Eight);
let mut writer = encoder
.write_header()
.wrap_err("failed to write png header")?;
piet_coregraphics::unpremultiply_rgba(&mut data);
writer
.write_image_data(&data)
.wrap_err("failed to write image data")?;
Ok(())
}
fn make_cg_ctx(size: Size) -> CGContext {
dbg!(&size);
let cg_ctx = CGContext::create_bitmap_context(
None,
size.width as usize,
size.height as usize,
8,
0,
&CGColorSpace::create_device_rgb(),
core_graphics::base::kCGImageAlphaPremultipliedLast,
);
cg_ctx
}
fn draw(rc: &mut impl RenderContext) -> Result<()> {
rc.clear(None, Color::WHITE);
Ok(())
}
I'm using these crates:
core-graphics = "0.22.3"
eyre = "0.6.5"
piet = "0.5.0"
piet-coregraphics = "0.5.0"
png = "0.17.2"
Running the above example, I get the following output:
[examples/render-test.rs:51] &size = 1.0W×1.0H
[examples/render-test.rs:33] data.len() = 64
[examples/render-test.rs:35] size.width as u32 = 1
[examples/render-test.rs:35] size.height as u32 = 1
Error: failed to write image data
Caused by:
wrong data size, expected 4 got 64
Location:
examples/render-test.rs:45:10
The PNG crate expects the image buffer to be 4 bytes long, which makes sense considering it's an RGBA image with 4 bytes per pixel, and it contains only one pixel. I'm not sure why piet is returning a 64-byte image buffer, and I don't really know enough about image formats to make a good guess. I opened the raw buffer in a hex editor, and it contains 0xff 0xff 0xff 0xff followed by 60 bytes of 0x00.
Is there some trimming that I'm supposed to do, or is there a settings mismatch in my code between png and piet?
EDIT: it seems there may be some minimum image size that I'm not exceeding. If I change the size to 100x400, it seems to work just fine. Is this restriction coming from piet, coregraphics, or png?
