コード全体
import java.io.File
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
object ImageUtil {
def resize(file: File): Unit = {
val original = ImageIO.read(file)
// 元ファイルの縦横サイズ(pixel)を取得
val originalWidth = original.getWidth.toDouble
val originalHeight = original.getHeight.toDouble
// 長辺を1とした縦横比を取得
val (widthScale, heightScale) =
if(originalWidth > originalHeight) (1d, originalHeight / originalWidth)
else (originalWidth / originalHeight, 1d)
// 長辺を200pxとして、縦横比を保ちリサイズ後の画像サイズを決定
val width = (200d * widthScale).toInt
val height = (200d * heightScale).toInt
val image = new BufferedImage(width, height, original.getType)
val scaled = original.getScaledInstance(width, height, java.awt.Image.SCALE_AREA_AVERAGING)
image.getGraphics.drawImage(scaled, 0, 0, width, height, null)
ImageIO.write(image, "jpeg", new File("/tmp/resized.jpeg"))
}
}
ざっくり解説
画像サイズの計算は問題ないと思うので、画像生成部分だけ。
val image = new BufferedImage(width, height, original.getType)
ここで画像サイズが決まる。まっさらなキャンバスを作るイメージ。
例ではリサイズ後の画像の大きさに合わせているので、余白なしの画像になる。
もし余白ありの正方形にしたい場合はこんな感じ。
// 長辺の長さを1辺とした正方形を作る
val scale = Math.max(width, height)
val image = new BufferedImage(scale, scale, original.getType)
次に、元画像をリサイズした画像データを取得する。
val scaled = original.getScaledInstance(width, height, java.awt.Image.SCALE_AREA_AVERAGING)
そして最初に作ったキャンバスにリサイズ後の画像を貼り付ける。
image.getGraphics.drawImage(scaled, 0, 0, width, height, null)
0, 0
はそれぞれキャンバスのx座標とy座標。指定座標を基準にリサイズ後画像をペーストするイメージ。
余白がある時は座標を調整すれば画像を左右上下に寄せたり中央にしたりできる。
最後にファイル出力して終わり。
ImageIO.write(image, "jpeg", new File("/tmp/resized.jpeg"))
おまけ: 余白の色を変える
余白がある場合、余白部分の色はデフォルトだと黒になる。
色を変える場合は、drawImage
の前に全体を好きな色で塗ってやればよい。
// 余白を白にする
image.getGraphics.setColor(Color.WHITE)
// 座標(0, 0)から、画像の縦横幅いっぱいに指定色で埋める
image.getGraphics.fillRect(0, 0, image.getWidth, image.getHeight)