Rustで画像をネガポジ変換

Rustの勉強を兼ねて、画像を読み込んでネガポジ変換するコードを書いてみました。 全然Rustらしさが無いですが、小さなことからコツコツと。

なお、今回はimageとうクレートを利用しました。

[dependencies]
image = "*"

実はネガポジ変換だけであれば、このクレートを使って画像を読み込んだ後、invert()というメソッドを叩いたら実現できてしまいます。 が、今回は勉強のために自分で各ピクセルの色情報(RGBa)を取得して弄りたかったので、その部分のみ自分で実装しました。

extern crate image;

use image::GenericImageView;
use image::GenericImage;
use image::DynamicImage;
use image::Rgba;

fn main() {
    let input = "/home/koji/Desktop/test.jpg";
    let output = "/home/koji/Desktop/test_inverted.jpg";
    let mut img: DynamicImage = image::open(input).unwrap();

    // 実は標準でメソッドが用意されている。これで反転できるよ
    // img.invert();
    invert(&mut img);

    img.save(output).unwrap();
}

fn invert(img: &mut DynamicImage)  {
    let (width, height) = img.dimensions();

    for y in 0..height {
        for x in 0..width {

            // 1pixelの情報を取得
            let mut pixel: Rgba<u8> = img.get_pixel(x, y);

            // RgbaはPixelトレイトを実装している。dataというプロパティでpixelの情報を取れる。
            // dataプロパティは、上記の型パラメタの通りu8型の配列になる。
            let red = pixel.data[0];
            let green = pixel.data[1];
            let blue = pixel.data[2];
            let alpha = pixel.data[3];

            // 手動で各色情報をネガポジ計算
            // 単純に各色のビットを反転するのみ。
            let new_color = [255-red, 255-green, 255-blue, alpha];
            let pixel: Rgba<u8> = Rgba(new_color);

            // put_pixel自体は、GenericImage(trait)で定義されて、DynamicImage(enum)で実装されている。
            // https://docs.rs/image/0.20.0/src/image/dynimage.rs.html#588
            // つまり、img変数の型であるDynamicImgeはちゃんとput_pixel()を持っている。
            // なので以下のimg.put_pixel()は普通に動くと思っちゃったけど、実はコンパイルエラーになる。
            // Rustではtrait自体を名前空間に置いておかないとその定義(trait)が確認できなくてコンパイルエラーになるらしい。
            // つまり、このコードに、
            // use image::GenericImage
            // を追加しないと以下はコンパイルエラーになってしまう。
            // Javaのinterfaceのつもりでtraitを使っていたのでココで混乱してしまった。。。
            img.put_pixel(x, y, pixel);
        }
    };
}

これで完了です。あとはcargo runすれば

のようにちゃんとネガポジ変換されて保存されました。

画像のR/W、各ピクセル情報の取得自体はimageを用いましたが、そのピクセル情報自体を弄る部分は自分で実装できました。 これで画像自体を色々な方法でRustから弄る基礎が分かったので色々試していこうと思います。

公開日:2018/09/28

Rust 画像処理

About me

ドイツの現地企業でWeb Developer/System Administratorとして働いているアラフォーおじさんです。

プログラミングとかコンピュータに関する事がメインですが、日常的なメモとか雑多なことも書きます。

Links :
目次