とにかく書く

日々の雑感や知り得たことを、とにかく書いています

JPEG 形式で画像を出力する

画像ビューアーを作っていて、いま表示している画像を保存できる機能を追加したいと思った。
ImageIO.write で保存しようとしたのだけれど、JPEG 形式だけ保存できなかった (ImageIO.write が false を返す) ため対処法をメモする。


結論からいえば、imageType に TYPE_INT_RGB を指定した BufferedImage クラスのインスタンスに画像を一旦コピーして出力する必要がある。
BufferedImage の imageType にアルファチャネルを持つ数値が指定されていると、JPEG 形式では対応していないため出力できないようだ。

以下を参考にしました。
stackoverflow.com

package application;

import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.BorderPane;

public class Main extends Application {
	@Override
	public void start(Stage primaryStage) {
		try {
			BorderPane root = new BorderPane();
			Scene scene = new Scene(root,400,400);
			scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
			primaryStage.setScene(scene);
			primaryStage.show();
			// 画像の読み込み 
			BufferedImage bufferedImage = ImageIO.read(new File("example.jpg"));
			WritableImage writableImage = SwingFXUtils.toFXImage(bufferedImage, null);
			// 画像の保存 (JPEG)
			bufferedImage = new BufferedImage((int)writableImage.getWidth(), (int)writableImage.getHeight(), BufferedImage.TYPE_INT_RGB);
			SwingFXUtils.fromFXImage(writableImage, bufferedImage);
			ImageIO.write(bufferedImage, "jpg", new File("output.jpg"));
			// 画像の保存 (PNG)
			bufferedImage = SwingFXUtils.fromFXImage(writableImage, null);
			ImageIO.write(bufferedImage, "png", new File("output.png"));
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}