I am using the Piston image
package to generate images.
fn get_image() -> image::DynamicImage {
image::DynamicImage::ImageRgba8(image::ImageBuffer::new(512, 512))
}
I have a hyper
web server, from which I would like to serve dynamically-generated images.
Based on the answer to How to create an in-memory object that can be used as a Reader or Writer in Rust?, I thought I might be able to use a Cursor<Vec<u8>>
as the destination. However, image
only seems to provide a method to write to a filename, not a Writer
like my cursor.
After looking through image
's documentation, I hoped there might be some way to use the image::png::PNGEncoder
struct directly. It provides a public method encode(self, data: &[u8], width: u32, height: u32, color: ColorType) -> Result<()>
. However, I wasn't sure what the data
argument is supposed to be, and I couldn't find any public declarations of the ColorType
s used by ImageBuffer
.
(&Get, "/image.png") => {
let v = {
let generated = get_image();
let mut encoded_image = Cursor::new(Vec::new());
let (width, heigth) = generated.dimensions();
{
let encoder = image::png::PNGEncoder::new(&encoded_image);
encoder.encode(unimplemented!("what goes here?"));
}
encoded_image.get_mut()
};
Box::new(futures::future::ok(
Response::new()
.with_header(ContentLength(v.len() as u64))
.with_body(v.clone()),
))
}
How do I encode a Piston GenericImage
to a format like PNG and get the result in memory?
I've adapted OP's code based on the
image
crate docs. It looks possible to make the original code to work. There is no need forCursor
but one needs to create a "by reference" adaptor for the instance ofWrite
implemented byVec
.Here is the code I actually used in my project. I get a reference to the raw pixels passed in as an
&[u8]
slice. Each pixel represents an 8 bit grayscale value. Here is a function that encodes the pixels into an in memory PNG image.You have a
DynamicImage
.I assume you mean
DynamicImage::save
.The method immediately before
save
iswrite_to
:This accepts any generic writer:
There's no need for a
Cursor
.I have no idea the best way to do this. I'd probably copy the generic image into a
DynamicImage
and then follow the above instructions.