このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
等間隔で間引きを行う方法は、
整数分の 1 のサイズにした変更できなかった。
任意のサイズに縮小するには、
間引きの方法を考える必要がある。
その代表的な手法に、近傍法がある。
これは、新しい画像のピクセルの位置に対応する、
元の画像のピクセル位置を計算し、
そのピクセルを利用するという方法である。
計算は、「表現ビット数の削減による減色」でやった、
範囲(区間)の計算と同じように考えるといい。
例えば、元の画像が 120 ピクセルの幅とし、
縮小後の画像が 100 ピクセルの幅とすると、
元の横方向は、0 から 119 までの区間と考え、
縮小後の横方向を 0 から 99 までの区間と考えられる。
なので、0 ~ 99 の範囲の値を、
0 ~ 119 の範囲に変換する式を使えば
縮小後の位置から元の位置が計算できる。
$original = int($shrunken * 119 / 99 + 0.5);
# BMP 読み込み。
my $data = read_bmp;
# 画像の高さと幅を取得。
my $scy = @$data;
my $scx = @{$data->[0]};
# 新しい画像の高さと幅を決める。
my $dcy = 75;
my $dcx = 100;
# 近い位置のピクセルを
# 画素を左上に持ってくる。
for (my $dy = 0; $dy < $dcy; ++$dy) {
for (my $dx = 0; $dx < $dcx; ++$dx) {
no integer;
# 新しい座標に対応する元の座標を求める。
my $sx = int($dx / ($dcx - 1) * ($scx - 1) + 0.5);
my $sy = int($dy / ($dcy - 1) * ($scy - 1) + 0.5);
$data->[$dy][$dx] = $data->[$sy][$sx];
}
}
# データの幅と高さを調整する。
$#$data = $dcy - 1;
$#$_ = $dcx - 1 foreach @$data;
# BMP を書き出す。
write_bmp($data, 24);
今日は、Windows のアイコンをサンプルとしてみよう。
Mixi の仕様を考え、元の画像は 120 x 90 としてある。
絵の部分と文字の部分は、画像としての特性が違うので、
昨日の考察どおり、アイコンは品質を保っているが、
文字は重要な部分が欠落して、非常に読みにくいことが分かる。