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}