はじめに
最近、会社に就職して暇つぶしがてらRustの勉強をはじめてみました。
第一印象は難しい!って感じですね。さすがにシステムプログラミング言語ですので、そこまで簡単なわけはないのですが。
今回は標準ライブラリを使うことに慣れるため、簡単な画像処理を標準ライブラリのimageを用いて行いたいと思います。
題材としては、グレースケールです。
#結果
テストで使う画像はRUSTの公式サイトからダウンロードしてきたフェリスの写真です。
グレースケール化した後の画像が以下の通りです。
#ソースコード
[dependencies]
image = "*"
設定ファイルにimage crateを追加する。
2021/7/7 現在ではversion 0.23.14がダウンロードされた。
extern crate image;
use std::env;
fn main() {
// 引数解析
let mut arg = env::args();
// 実行コマンドをスキップ
arg.next();
// 引数チェック
let image_path = match arg.next() {
None => {
println!("error");
return
},
Some(s) => s,
};
//引数を得られているかデバック
println!("Image Path is {}",image_path);
test(image_path);
}
fn test(path : String){
// ファイル展開とエラーチェック(.unwrap())
let img = image::open(path).unwrap();
let img = img.to_rgb8();
let size_x = img.width();
let size_y = img.height();
// グレースケール用のデータを作成
let mut gray_img = image::GrayImage::new(size_x,size_y);
let pix = img.get_pixel(0,0);
for y in 0 .. size_y {
for x in 0 .. size_x {
// ピクセルデータの取得
let pix = img.get_pixel(x,y);
// GrayScale BT.709
// V = 0.2126*R + 0.7152*G + 0.0722*B
let val = [((pix[0] as f32 * 0.2126) as u32 +
(pix[1] as f32 * 0.7152) as u32 +
(pix[2] as f32 * 0.0722) as u32) as u8;1];
// ピクセルデータをあらかじめ作っておいたグレースケールデータに書き込む
gray_img.put_pixel(x,y,image::Luma(val));
}
}
// 画像をファイルとして保存する。エラーチェックも忘れずに
gray_img.save("./gray.png").unwrap();
}
今回はあえて一つ一つのデータを取得し、加工し、保存するような書き方を行った。
image crateにはグレースケール化する関数も存在するので、そちらでもよかったのだが。。。
おわりに
Rust はむずかしいな。
特に型が厳しすぎるので、慣れるまでコンパイラに怒られ続けるんだろうな。
次は何を題材に練習しようか悩みますね。
参考
https://kcs1959.jp/archives/4064/research/rust_image-crate_example
https://docs.rs/image/0.23.14/image/index.html