練習問題

1. グラデーション2

実行例に示す画像のような255×255の画像を作成してください. 画像ファイル名は gradiation2.png とし,クラス名は Gradiation2 としてください.

実行例

ヒント

  • 例題1を元に作成しましょう.
  • setRGB に指定する色を以下のルールで指定すれば良いです.
    • 右上が青であるため,xが大きくなるにつれ,青成分を増加させるようにしましょう.
    • 左下が赤であるため,yが大きくなるにつれ,赤成分(y << 16)を増加させましょう.
    • 2つの成分を論理和で合成すると良いでしょう(x | y << 16).

2. ファイルフォーマット変換

2つのコマンドライン引数を受け取り,第1引数で与えられた画像を読み込み,第2引数で与えられたファイルに画像を出力してください. ただし,第2引数のファイル名の拡張子で指定されたフォーマットで画像を出力してください. クラス名は ImageFormatConverter としてください.

実行例

$ java ImageFormatConverter sample1.png a2-1.jpg
$ file a2-1.jpg  # 出力された a2-1.jpg のフォーマットを調べる.
a2-1.jpg: JPEG image data, JFIF standard 1.02, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 255x255, components 3
$ java ImageFormatConverter sample1.png a2-2.bmp
$ file a2-2.bmp  # 出力された a2-1.bmp のフォーマットを調べる.
a2-2.bmp: data

ヒント

  • 拡張子は,例題2findDestNameextensionで取得できています. この extensionをそのまま出力フォーマットの指定で用いると良いです.

3. グレースケール画像への変換

コマンドライン引数で与えられた画像をグレースケール画像に変換してgray.pngに出力してください. クラス名は GrayScaleFilter としてください. グレースケールへの変換は, BufferedReader の実体を作成する時に, BufferedImage.TYPE_BYTE_GRAY を指定するとグレースケール画像に変換できます.

実行例

グレースケール画像 グレースケール画像

ヒント

  • 読み込んだ画像(source)とは別の BufferedImage の実体を作成します(grayImage).
    • 作成の際に BufferedImage.TYPE_BYTE_GRAY を指定しましょう.
    • 大きさは元の画像の大きさと同じにしましょう.
      • BufferedImage grayImage = new BufferedImage(source.getWidth(), source.getHeight(), BufferedImage.TYPE_BYTE_GRAY)
  • grayImage から createGraphics メソッドを用いて Graphics2D の実体(g2)を取得します.
    • Graphics2D g2 = grayImage.createGraphics();
  • g2.drawImage で元の画像をgrayImageに描画しましょう.
    • g2.drawImage(source, 0, 0, null);
  • grayImage をファイルに出力して終了です.

4. 画像の回転

コマンドライン引数で与えられた画像を,同じくコマンドライン引数で与えられた角度(度数法)だけ回転させて出力してください. ただし,画像が切れないように大きさを調整してください. 角度は 0〜90 の範囲とします. クラス名は ImageRotatorとしてください. グレースケール画像と同様に,元画像とは別の BufferedImageの実体を作成し,そこに回転した画像を描画しましょう.

実行例

$ java ImageRotator sample1.png 60 dset.png

回転後の画像 回転後の画像

ヒント

  • 以下の説明では,元画像(source)の横幅を $w$,高さを$h$とし,回転角度を $\theta$ とします.

変換後の画像の大きさ

  • 以下の画像では$\theta=60$の例を示しています(クリックして確認してください).
  • このように,回転後の画像の横幅は,$w\sin\theta + w\cos\theta$ です.
    • 同様に,回転後の画像の高さは $h\sin\theta + h\cos\theta$ です.
画像の回転の様子

処理手順

  • AffineTransformの実体を作成し, $\theta$だけ回転させた後,$x$軸方向に $w\sin\theta$ だけ移動させます.
    • 変換を指定した順序とは逆の順序で変換が適用される点に注意してください.
      • つまり,プログラムでは,平行移動(translate)した後,回転(rotate)させてください. 以下のようなプログラムで実現できるでしょう.
Dobule angle = Math.toRadians(degree);
AffineTransform affine = new AffineTransform();
affine.translate(width * Math.sin(angle), 0d);
affine.rotate(angle);
// ... 出力先画像の Graphics2D の実体を取得し,g2 に代入する.
g2.drawImage(source, affine, null);

5. 自由課題

与えられた画像に対して何らかの変換を行いファイルに出力してください. クラス名は,ImageEditor としてください.