photon_rs/
text.rs

1//! Draw text onto an image.
2//! For extended graphic design/text-drawing functionality, see [GDL](https://github.com/silvia-odwyer/gdl),
3//! which is a graphic design library, compatible with Photon.
4
5use crate::iter::ImageIterator;
6use crate::{helpers, PhotonImage};
7use image::{DynamicImage, Rgba};
8use imageproc::distance_transform::Norm;
9use imageproc::drawing::draw_text_mut;
10use imageproc::morphology::dilate_mut;
11use rusttype::{Font, Scale};
12
13#[cfg(feature = "enable_wasm")]
14use wasm_bindgen::prelude::*;
15
16/// Add bordered-text to an image.
17/// The only font available as of now is Roboto.
18/// Note: A graphic design/text-drawing library is currently being developed, so stay tuned.
19///
20/// # Arguments
21/// * `photon_image` - A PhotonImage.
22/// * `text` - Text string to be drawn to the image.
23/// * `x` - x-coordinate of where first letter's 1st pixel should be drawn.
24/// * `y` - y-coordinate of where first letter's 1st pixel should be drawn.
25/// * `font_size` - Font size in pixels of the text to be drawn.
26///
27/// # Example
28///
29/// ```no_run
30/// // For example to draw the string "Welcome to Photon!" at 10, 10:
31/// use photon_rs::native::open_image;
32/// use photon_rs::text::draw_text_with_border;
33///
34/// // Open the image. A PhotonImage is returned.
35/// let mut img = open_image("img.jpg").expect("File should open");
36/// draw_text_with_border(&mut img, "Welcome to Photon!", 10_i32, 10_i32, 90_f32);
37/// ```
38#[cfg_attr(feature = "enable_wasm", wasm_bindgen)]
39pub fn draw_text_with_border(
40    photon_img: &mut PhotonImage,
41    text: &str,
42    x: i32,
43    y: i32,
44    font_size: f32,
45) {
46    let mut image = helpers::dyn_image_from_raw(photon_img).to_rgba8();
47
48    let mut image2: DynamicImage =
49        DynamicImage::new_luma8(image.width(), image.height());
50
51    let font = Vec::from(include_bytes!("../fonts/Roboto-Regular.ttf") as &[u8]);
52    let font = Font::try_from_bytes(&font).unwrap();
53    let scale = Scale {
54        x: font_size * 1.0,
55        y: font_size,
56    };
57    draw_text_mut(
58        &mut image2,
59        Rgba([255u8, 255u8, 255u8, 255u8]),
60        x,
61        y,
62        scale,
63        &font,
64        text,
65    );
66
67    let mut image2 = image2.to_luma8();
68    dilate_mut(&mut image2, Norm::LInf, 4u8);
69
70    // Add a border to the text.
71    for (x, y) in ImageIterator::with_dimension(&image2.dimensions()) {
72        let pixval = 255 - image2.get_pixel(x, y)[0];
73        if pixval != 255 {
74            let new_pix = Rgba([pixval, pixval, pixval, 255]);
75            image.put_pixel(x, y, new_pix);
76        }
77    }
78
79    draw_text_mut(
80        &mut image,
81        Rgba([255u8, 255u8, 255u8, 255u8]),
82        x + 10,
83        y - 10,
84        scale,
85        &font,
86        text,
87    );
88    let dynimage = image::DynamicImage::ImageRgba8(image);
89    photon_img.raw_pixels = dynimage.into_bytes();
90}
91
92/// Add text to an image.
93/// The only font available as of now is Roboto.
94/// Note: A graphic design/text-drawing library is currently being developed, so stay tuned.
95///
96/// # Arguments
97/// * `photon_image` - A PhotonImage.
98/// * `text` - Text string to be drawn to the image.
99/// * `x` - x-coordinate of where first letter's 1st pixel should be drawn.
100/// * `y` - y-coordinate of where first letter's 1st pixel should be drawn.
101/// * `font_size` - Font size in pixels of the text to be drawn.
102///
103/// # Example
104///
105/// ```no_run
106/// // For example to draw the string "Welcome to Photon!" at 10, 10:
107/// use photon_rs::native::open_image;
108/// use photon_rs::text::draw_text;
109///
110/// // Open the image. A PhotonImage is returned.
111/// let mut img = open_image("img.jpg").expect("File should open");
112/// draw_text(&mut img, "Welcome to Photon!", 10_i32, 10_i32, 90_f32);
113/// ```
114#[cfg_attr(feature = "enable_wasm", wasm_bindgen)]
115pub fn draw_text(
116    photon_img: &mut PhotonImage,
117    text: &str,
118    x: i32,
119    y: i32,
120    font_size: f32,
121) {
122    let mut image = helpers::dyn_image_from_raw(photon_img).to_rgba8();
123
124    let font = Vec::from(include_bytes!("../fonts/Roboto-Regular.ttf") as &[u8]);
125    let font = Font::try_from_bytes(&font).unwrap();
126    let scale = Scale {
127        x: font_size * 1.0,
128        y: font_size,
129    };
130
131    draw_text_mut(
132        &mut image,
133        Rgba([255u8, 255u8, 255u8, 255u8]),
134        x,
135        y,
136        scale,
137        &font,
138        text,
139    );
140    let dynimage = image::DynamicImage::ImageRgba8(image);
141    photon_img.raw_pixels = dynimage.into_bytes();
142}