Rust の imageproc で斜体 (italic) を表現する方法

  • URLをコピーしました!

Rust、特に画像生成周りの情報がネット上に全然ないので、備忘録的に残しておきます。

目次

やりたいこと

まず、以下のようなシンプルな「Hello, World!」と画像に出力するだけのプログラムがあったとします。

use image::{DynamicImage, Rgba};
use imageproc::drawing::draw_text_mut;
use once_cell::sync::Lazy;
use rusttype::{Font, Scale};

const INTER: Lazy<Font> =
    Lazy::new(|| Font::try_from_bytes(include_bytes!("../fonts/Inter-Regular.ttf")).unwrap());

fn main() {
    let mut img = DynamicImage::new_rgba8(400, 100);

    draw_text_mut(
        &mut img,
        Rgba::from([0, 0, 0, 255]),
        10,
        10,
        Scale::uniform(60.0),
        &INTER.clone(),
        "Hello, World!",
    );

    img.save("image.png").unwrap()
}

これを実行すると、以下のような簡単な画像が出力されます。

このテキストを斜体で描画したいです。

実現方法

imageproc には傾けて文字を描画する機能がなく、また描画するオブジェクトの傾きを設定しておく方法もないため、まず傾けた文字だけの画像を作り、それを元の画像に重ねる方法を取ります。

簡単にコーディングしたものが以下です。

use image::{imageops::overlay, DynamicImage, Rgba, RgbaImage};
use imageproc::{
    drawing::draw_text_mut,
    geometric_transformations::{warp_into, Interpolation, Projection},
};
use once_cell::sync::Lazy;
use rusttype::{Font, Scale};

const INTER: Lazy<Font> =
    Lazy::new(|| Font::try_from_bytes(include_bytes!("../fonts/Inter-Regular.ttf")).unwrap());

fn main() {
    let mut img = DynamicImage::new_rgba8(400, 100);

    let mut text_image = DynamicImage::new_rgba8(300, 80);
    let mut italic_text_image = RgbaImage::new(300, 80);
    draw_text_mut(
        &mut text_image,
        Rgba::from([0, 0, 0, 255]),
        0,
        0,
        Scale::uniform(60.0),
        &INTER.clone(),
        "Hello, World!",
    );

    let matrix = Projection::from_matrix([
        1_f32,    // 固定
        -0.2_f32, // 傾きの強さ (値を小さくすればするほど強くなる)
        4.8_f32,  // 傾けると x 軸方向がズレて切れてしまうので、いい感じに修正する
        0_f32,    // 固定
        1_f32,    // 固定
        0_f32,    // 固定
        0_f32,    // 固定
        0_f32,    // 固定
        1_f32,    // 固定
    ]);
    warp_into(
        &text_image.to_rgba8(),
        &matrix.unwrap(),
        Interpolation::Bilinear, // Bicubic を指定するとさらに滑らかになるが、遅くなる
        Rgba([0, 0, 0, 0]),
        &mut italic_text_image,
    );

    overlay(&mut img, &italic_text_image, 10, 10);

    img.save("image.png").unwrap()
}

これを実行すると、以下のように斜体のテキストが出力されました。

このように疑似的に斜体を表現することができます。傾きやオーバーレイのサイズなどは適宜調節してください。

なお、この記事のソースコードは GitHub に公開しています。あわせてご覧ください。

参考

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする


目次