Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draw text with outline #479

Open
Fogapod opened this issue Dec 10, 2021 · 3 comments
Open

Draw text with outline #479

Fogapod opened this issue Dec 10, 2021 · 3 comments

Comments

@Fogapod
Copy link

Fogapod commented Dec 10, 2021

Hello, #157 mentions text outline, but it was not implemented.

How could outline support be added for text drawing? Is it rendering text twice on top of itself with smaller size or something else?

EDIT: actually, drawing text on top of itself with offset would not work because that would create projection. the only solution i see for this is drawing each letter individually, but that is far from ideal.

@Fogapod
Copy link
Author

Fogapod commented Dec 11, 2021

Found this solution:

// a modified version of:
// https://github.com/silvia-odwyer/gdl/blob/421c8df718ad32f66275d178edec56ec653caff9/crate/src/text.rs#L23
#[allow(clippy::too_many_arguments)]
pub fn draw_text_with_border<'a>(
    canvas: &mut DynamicImage,
    x: u32,
    y: u32,
    scale: Scale,
    font: &'a Font<'a>,
    text: &str,
    color: Rgba<u8>,
    outline_color: Rgba<u8>,
    outline_width: u8,
) {
    let mut image2: DynamicImage = DynamicImage::new_luma8(canvas.width(), canvas.height());

    imageproc::drawing::draw_text_mut(&mut image2, color, x, y, scale, font, text);

    let mut image2 = image2.to_luma8();
    imageproc::morphology::dilate_mut(
        &mut image2,
        imageproc::distance_transform::Norm::LInf,
        outline_width,
    );

    // Add a border to the text.
    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 {
                canvas.put_pixel(x, y, outline_color);
            }
        }
    }
    imageproc::drawing::draw_text_mut(canvas, color, x, y, scale, font, text);
}

Would be nice to have somthing similar in the library

@nathanielfernandes
Copy link

Found this solution from: https://github.com/fogleman/gg/blob/master/examples/meme.go
Looks better as well

pub fn draw_text_with_outline<'a>(
    canvas: &mut DynamicImage,
    x: i32,
    y: i32,
    scale: Scale,
    font: &'a Font<'a>,
    text: &str,
    color: Rgba<u8>,
    outline_color: Rgba<u8>,
    outline_width: i32,
) {
    for dy in -outline_width..outline_width + 1 {
        for dx in -outline_width..outline_width + 1 {
            if dx * dx + dy * dy >= outline_width * outline_width {
                continue;
            }

            imageproc::drawing::draw_text_mut(
                canvas,
                outline_color,
                x + dx,
                y + dy,
                scale,
                font,
                text,
            );
        }
    }

    imageproc::drawing::draw_text_mut(canvas, color, x, y, scale, font, text);
}

@Fogapod
Copy link
Author

Fogapod commented Jun 10, 2023

This version does look better but runs 3 times slower in my tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants