How can I convert an image::ImageBuffer into an image::DynamicImage?

Viewed 194

I am trying to overlay text on an image, and get the resulting image as a vector of bytes. There's no method to get the encoded bytes from an imagebuffer, but there is one for a dynamicimage, however I don't know how to convert an imagebuffer to a dynamicimage. I couldn't seem to find any information on this except here: https://github.com/image-rs/image/issues/964, yet this does not give a real answer. as_raw() and into_raw() return a Container which may not be a Vec<u8> or a &[u8], which is what I'm looking for.

use image::DynamicImage;
use image::Rgba;
use imageproc::distance_transform::Norm;
use imageproc::drawing::draw_text_mut;
use imageproc::morphology::dilate_mut;
use rusttype::{Font, Scale};

fn overlay_text(text: &str, img_data: &[u8]) -> Vec<u8> {
    let sb_img = image::load_from_memory(img_data).unwrap();

    let mut image = sb_img.to_rgba8();

    let mut image2: DynamicImage = DynamicImage::new_luma8(image.width(), image.height());

    let font: &[u8] = include_bytes!(".fonts/DejaVuSans.ttf") as &[u8];
    let font = Font::try_from_bytes(font).unwrap();

    let scale = Scale {
        x: image.width() as f32 * 0.2,
        y: image.height() as f32 * 0.2,
    };

    let x = (image.width() as f32 * 0.10) as u32;
    let y = (image.width() as f32 * 0.10) as u32;
    draw_text_mut(
        &mut image2,
        Rgba([255u8, 255u8, 255u8, 255u8]),
        x,
        y,
        scale,
        &font,
        text,
    );

    let mut image2 = image2.to_luma8();
    dilate_mut(&mut image2, Norm::LInf, 4u8);

    for x in 0..image2.width() {
        for y in 0..image2.height() {
            let pixval = 255 - image2.get_pixel(x, y).0[0];
            if pixval != 255 {
                let new_pix = Rgba([pixval, pixval, pixval, 255]);
                image.put_pixel(x, y, new_pix);
            }
        }
    }

    draw_text_mut(
        &mut image,
        Rgba([255u8, 255u8, 255u8, 255u8]),
        x,
        y,
        scale,
        &font,
        text,
    );

    // image2.into_bytes() method does not exist
}

fn main() {
    let imgbytes = &reqwest::blocking::get("https://example.com/image.png")
        .unwrap()
        .bytes()
        .unwrap()
        .to_vec() as &[u8];
    overlay_text("some text", imgbytes);
}
0 Answers
Related