An image library


#1

I have an image and I want to draw a text on it using Rust. How can I do that? Is the library “image” suitable for this? I haven’t found anything related to text in its documentation.


#2

Here’s an example of how you can do that using the png crate for encoding/decoding PNGs and the Cairo graphics library (via the cairo-rs crate) for drawing:

extern crate png;
extern crate cairo;

use std::io::BufWriter;
use std::fs::File;

// for `encoder.set()`
use png::HasParameters;

fn main() {
    // open the image file
    let file = File::open("/path/to/some/file.png")
        .expect("Failed to open the file");

    // parse the metadata
    let decoder = png::Decoder::new(file);
    let (info, mut reader) = decoder.read_info()
        .expect("Invalid PNG");

    // extract the raw image
    let mut data = vec![0; info.buffer_size()];
    reader.next_frame(&mut data)
        .expect("Invalid PNG");

    // create a Cairo image surface
    let mut surface = cairo::ImageSurface::create_for_data(
        data.into_boxed_slice(),
        |_| {},  // just drop it
        cairo::Format::ARgb32,
        info.width as i32,
        info.height as i32,
        info.line_size as i32
    );

    // initialize a Cairo drawing context
    let context = cairo::Context::new(&surface);
    // draw some text
    context.select_font_face(
        "serif",
        cairo::FontSlant::Normal,
        cairo::FontWeight::Normal
    );
    context.set_font_size(20.0);
    context.set_source_rgb(1.0, 0.0, 0.0);
    context.move_to(50.0, 50.0);
    context.show_text("Hello");

    drop(context);
    let data = surface.get_data().unwrap();

    // save the image back
    let file = File::create("/path/to/output/file.png")
        .expect("Failed to create the output file");
    let buf_writer = BufWriter::new(file);
    let mut encoder = png::Encoder::new(buf_writer, info.width, info.height);
    encoder.set(png::ColorType::RGBA).set(png::BitDepth::Eight);
    let mut writer = encoder.write_header().unwrap();
    writer.write_image_data(&data)
        .expect("Failed to write the image data");
}

#3

why not “magick_rust”?


#4

The imageproc crate is based on the image crate and supports this. See this example: https://github.com/PistonDevelopers/imageproc/blob/master/examples/font.rs