PNGを端末に表示するプログラムをRustで書いた

PNGを端末に表示するプログラムを作りました。

github.com

使い方

cargo run /Path/to/Windows_logo.png

とすると、👇のように端末に画像が表示されます。透過画像も表示できます。

ちなみに、PNGの画像形式は何パターンかあるのですが、そのすべてに対応してるわけではないので、表示できない画像もあります。あしからず。

続きを読む

PNGの規格を簡単に説明する

PNGの規格を勉強する機会があったので、その内容を簡単に説明します*1

PNGはいくつかの"チャンク"が集まって構成されています。例えば、IHDRチャンクやIDATチャンク、PLTEチャンクなどがあります。では、PNGファイルという単なるバイト列から、どのようにチャンクを抽出すれば良いのでしょうか?

これは、PNGファイルの構造を知ることでわかります。

*1:PNGの規格自体はRFC公開されている

続きを読む

機能追加と同時にリファクタリングをしてもいいか

「機能追加と同時にリファクタリングをしてもいい」という記事がはてブに上がっていたので、思うところを述べる。

scrapbox.io

結論

続きを読む

iter()とinto_iter()の違いを整理した

VectorIteratorに変換する時にいつも混乱していたので整理した。

混乱

あるVectorの要素すべてを3倍するコードを考える。

fn main() {
    let vec1 = vec![1,2,3,4,5];
    let vec2 = vec1.iter()
                   .map(|i| i * 3)
                   .collect::<Vec<i32>>();

    println!("{:?}", vec1);
    println!("{:?}", vec2);
}

このコードはコンパイルできるが、以下のような疑問がある。

  1. 5行目で vec1はなぜ使えるのか? 3行目の vec1.iter()で使われているじゃないか!
  2. map(|i| i * 3)iは参照なのか値なのか?

これらの疑問に関する答えは、

  1. iter()Vectorをmoveしない。into_iter()Vectorをmoveする。
  2. iter()Vectorから「参照のコレクションであるIterator」を作成し、into_iter()Vectorから「値のコレクションであるIterator」を作成する。

ということになる。

続きを読む