Skip to content

Commit

Permalink
Text overlay (#14)
Browse files Browse the repository at this point in the history
Resolve: #13

Signed-off-by: Thibault Meyer <meyer.thibault@gmail.com>
  • Loading branch information
thibaultmeyer authored Sep 26, 2024
1 parent 3fd6444 commit 68fba0c
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 9 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ publish = false


[dependencies]
ab_glyph = "0.2.28"
chrono = "0.4.38"
clap = { version = "4.5.4", features = ["derive"] }
confy = "0.6.1"
image = "0.25.2"
imageproc = "0.25.0"
reqwest = { version = "0.12.4", features = ["blocking", "json"] }
serde = "1.0.202"
serde_derive = "1.0.202"
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ background.
* `image_dimension_width` The "width" dimension of the wallpaper
* `image_dimension_height` The "height" dimension of the wallpaper
* `target_filename` The location where is stored the wallpaper
* `text_overlay_position` (OPTIONAL) Add text overlay containing information about the picture. Value must be
surrounded with simple quote. Accepted values are: `BOTTOM_LEFT`, `BOTTOM_RIGHT`, `TOP_LEFT`, `TOP_RIGHT`
* `text_overlay_position_offset_x` (OPTIONAL) Applies an offset on the X-axis of the text overlay.
* `text_overlay_position_offset_y` (OPTIONAL) Applies an offset on the Y-axis of the text overlay.
* `exec_apply_wallpaper` (OPTIONAL) Command to execute for applying wallpaper, the
string accept following variables: `image_dimension_width`, `image_dimension_height`,
and `target_filename`
Expand Down
Binary file added res/font/Ubuntu-Regular.ttf
Binary file not shown.
27 changes: 19 additions & 8 deletions src/bingwallpaper/bingwallpaperchanger.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use chrono::{DateTime, Utc};
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
use std::env;
#[cfg(target_os = "windows")]
Expand All @@ -11,9 +12,6 @@ use std::io::Write;
use std::path::Path;
use std::process::Command;
use std::time::SystemTime;

use chrono::{DateTime, Utc};

#[cfg(target_os = "windows")]
use winapi::ctypes::c_void;
#[cfg(target_os = "windows")]
Expand All @@ -23,7 +21,7 @@ use winvd::{get_desktop_count, get_desktops};
#[cfg(target_os = "windows")]
use winver::WindowsVersion;

use crate::bingwallpaper::{BingAPIClient, BingWallpaperConfiguration};
use crate::bingwallpaper::{BingAPIClient, BingWallpaperConfiguration, TextOverlay};

/// Retrieves from Bing API and applies the wallpaper of the day.
///
Expand All @@ -43,7 +41,7 @@ impl BingWallpaperChanger {
/// Creates a new instance.
///
/// Arguments
/// * `configuration` - The configuration to use
/// * `configuration` - The Bing Wallpaper configuration to use
///
/// # Examples
///
Expand Down Expand Up @@ -102,6 +100,9 @@ impl BingWallpaperChanger {
self.bing_api_client.download_image(&bing_image, &self.configuration.target_filename)?;
}

// Overlay
TextOverlay::apply_overlay(&self.configuration, bing_image.title, bing_image.copyright);

// Change current wallpaper (if requested)
if must_change_wallpaper {
return self.change_wallpaper();
Expand All @@ -118,7 +119,7 @@ impl BingWallpaperChanger {

/// Returns the date (UTC) as a String following the format "%Y%m%d" of the current wallpaper.
///
/// In case of current wallpaper does not exists, "00000000" will be return.
/// In case of current wallpaper does not exist, "00000000" will be return.
fn get_date_current_wallpaper(&self) -> String {
match Path::new(self.configuration.target_filename.as_str()).metadata() {
Err(_) => String::from("00000000"),
Expand All @@ -137,7 +138,12 @@ impl BingWallpaperChanger {
if self.configuration.exec_apply_wallpaper.is_some() {
self.exec_apply_wallpaper();
} else {
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))] {
#[cfg(any(
target_os = "linux",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))] {
self.change_wallpaper_linux();
}

Expand Down Expand Up @@ -186,7 +192,12 @@ impl BingWallpaperChanger {
}

/// Changes the wallpaper with the given picture on Linux.
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
#[cfg(any(
target_os = "linux",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
fn change_wallpaper_linux(&self) {
let session = env::var("DESKTOP_SESSION").unwrap();

Expand Down
8 changes: 7 additions & 1 deletion src/bingwallpaper/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ pub struct BingWallpaperConfiguration {
pub(crate) image_dimension_width: u32,
pub(crate) image_dimension_height: u32,
pub(crate) target_filename: String,
pub(crate) text_overlay_position: Option<String>,
pub(crate) text_overlay_position_offset_x: Option<u32>,
pub(crate) text_overlay_position_offset_y: Option<u32>,
pub(crate) exec_apply_wallpaper: Option<String>,
pub(crate) proxy_url: Option<String>,
}
Expand All @@ -25,7 +28,10 @@ impl Default for BingWallpaperConfiguration {
loop_interval_second: 900.into(),
image_dimension_height: 1080,
image_dimension_width: 1920,
target_filename: "/tmp/bingwallpaper.png".into(),
target_filename: "/tmp/bingwallpaper.jpg".into(),
text_overlay_position: None,
text_overlay_position_offset_x: None,
text_overlay_position_offset_y: None,
exec_apply_wallpaper: None,
proxy_url: None,
}
Expand Down
2 changes: 2 additions & 0 deletions src/bingwallpaper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ pub use self::arguments::BingWallpaperArguments;
pub use self::bingapiclient::BingAPIClient;
pub use self::bingwallpaperchanger::BingWallpaperChanger;
pub use self::configuration::BingWallpaperConfiguration;
pub use self::textoverlay::TextOverlay;

mod arguments;
mod bingapiclient;
mod bingwallpaperchanger;
mod configuration;
mod textoverlay;
55 changes: 55 additions & 0 deletions src/bingwallpaper/textoverlay.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use crate::bingwallpaper::BingWallpaperConfiguration;
use ab_glyph::{FontRef, PxScale};
use image::{ImageReader, Rgb, RgbImage};
use imageproc::drawing::draw_text;

/// Text overlay
pub struct TextOverlay {}

impl TextOverlay {
/// Applies text overlay.
///
/// # Arguments
/// * `configuration - The Bing Wallpaper configuration to use
/// * `line1` - First line of text
/// * `line2` - Second line of text
///
/// # Examples
///
/// ```
/// use textoverlay::TextOverlay;
///
/// TextOverlay::apply_overlay(configuration, "Title", "Description")
/// ```
pub fn apply_overlay(configuration: &BingWallpaperConfiguration, line1: String, line2: String) {
if configuration.text_overlay_position.is_none() {
return;
}

let font = FontRef::try_from_slice(include_bytes!("../../res/font/Ubuntu-Regular.ttf")).unwrap();
let font_scale = PxScale::from(30.0);
let (mut pos_x, mut pos_y) = match configuration.text_overlay_position.clone().unwrap().to_uppercase().as_str() {
"TOP_LEFT" => (60i32, 60i32),
"BOTTOM_LEFT" => (60i32,
configuration.image_dimension_height as i32 - (font_scale.x as i32 * 2) - 60 - 5),
"TOP_RIGHT" => (configuration.image_dimension_width as i32 - (12i32 * line2.len() as i32) - 55,
60i32),
"BOTTOM_RIGHT" => (configuration.image_dimension_width as i32 - (12i32 * line2.len() as i32) - 55,
configuration.image_dimension_height as i32 - (font_scale.x as i32 * 2) - 60 - 5),
_ => (60i32, 60i32),
};

if configuration.text_overlay_position_offset_x.is_some() {
pos_x += configuration.text_overlay_position_offset_x.unwrap() as i32
}
if configuration.text_overlay_position_offset_y.is_some() {
pos_y += configuration.text_overlay_position_offset_y.unwrap() as i32;
}

let image = ImageReader::open(&configuration.target_filename).unwrap().decode().unwrap();
let image = RgbImage::from(image);
let image = draw_text(&image, Rgb([255u8, 255u8, 255u8]), pos_x, pos_y, font_scale, &font, &line1);
let image = draw_text(&image, Rgb([255u8, 255u8, 255u8]), pos_x, pos_y + font_scale.x as i32 + 5, font_scale, &font, &line2);
image.save(&configuration.target_filename).unwrap();
}
}

0 comments on commit 68fba0c

Please sign in to comment.