Webブラウザで利用される画像形式として、写真はJpeg、ロゴやイラストはGIF、PNG形式で保存することが一般的となっていると思われる。GIFやPNGでは透過(アルファチャンネル)やアニメーションの機能も備わっており機能的には十分であるが、Webサイトの利便性やSEO対策の面からファイルサイズが小さい画像フォーマットは望まれ続けている。
従来の画像フォーマットよりもファイルサイズが小さい次世代の画像フォーマットとしては、WebPやAVIFといった規格が公開されている。その中でもWebPについては、2021年11月現在、ほぼすべてのWebブラウザで対応できており、利用する場面も増えてくることが予想される。今回はJavaFXでWebP画像の入出力方法を確認する。
■ WebPとは?
Googleが2010年9月に公開したオープンな画像フォーマット(
*1)(
*2)。ロスレス圧縮、非可逆圧縮の両方に対応しており、透過(アルファチャンネル)やアニメーションにも対応している。特徴としてファイルサイズの小ささが上げられ、ロスレスの場合にはPNGよりもファイルサイズが26%小さく、非可逆圧縮の場合には25〜34%小さくできるとGoogleは謳っている。
2021年11月時点での各ブラウザでの対応状況は以下の通りであり、ほぼすべてのブラウザで対応している。(緑が「対応済み」、黄色が「部分対応」、赤が「未対応」。2022年6月にサポートを打ち切るIE(
*3)や、Safari(iOS除く)で対応できていない程度)
引用「
Can I use(WebP)」
なお、WebPの後継と言われているAVIFの対応状況は以下のとおりであり、まだ普及するまでには至っていないようである。
引用「
Can I use(AVIF)」
■ WebPライブラリ「webp-imageio」
JavaのWebPライブラリとして、「webp-imageio」を利用する。以下にGitのリポジトリが公開されており、ライセンスは「Apache Software License version 2.0.」(著作権表示等の事項を守れば商用も可能(
*4))とのこと。
最新ソースを試したい場合には、上記ページからソースをダウンロードしてコンパイルする必要があるが、Maven Repositoryに登録済みであるため、安定版を以下からライブラリ(jarファイル)をダウンロードできる。2021年11月11日時点では、バージョン「0.1.6」が最新である。
◇ダウンロード方法(バージョン0.1.6の場合)
①「0.1.6」をクリック
② 「jar(1.0MB)」をクリック
③ ライブラリ「webp-imageio-0.1.6.jar」がダウンロードされる。
上記方法でダウンロードしたjarファイルを、クラスパスに通せばライブラリが可能となる。クラスパスの追加方法については、
こちらの記事を参照のこと。
■ WebPファイルの読込・表示
「webp-imageio」を利用してWebPファイルを読み込み、JavaFXで表示するサンプルプログラムを示す。
◇リソース JavaFXプロジェクトの作成方法は
こちらを参照。
【実行引数】
--module-path "(javaFXの配置パス)\lib" --add-modules javafx.controls,javafx.fxml
【使用画像】
Googleの
WebP Gallaryの画像を利用する。
package application;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.FileImageInputStream;
import com.luciad.imageio.webp.WebPReadParam;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
/**
*
* sejda-pdf/webp-imageio
*
* GitHub
* https://github.com/sejda-pdf/webp-imageio
*
* Maven Repository
* https://mvnrepository.com/artifact/org.sejda.imageio/webp-imageio
*
* @author Da@
*
*/
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
// Scene Graphクラス
AnchorPane root = new AnchorPane();
// WEBP画像読込
WritableImage img = null;
try {
// 前準備
ImageReader reader = ImageIO.getImageReadersByMIMEType("image/webp").next();
WebPReadParam readParam = new WebPReadParam();
readParam.setBypassFiltering( true );
// ファイルを開く
reader.setInput( new FileImageInputStream( new File("img/1.webp") ) );
BufferedImage bimg = reader.read( 0 , readParam );
// awtからjavaFXへ変換
img = SwingFXUtils.toFXImage( bimg , null );
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 画像をウィンドウに追加
ImageView view = new ImageView( img );
root.getChildren().add( view );
// Sceneクラス
Scene scene = new Scene(root);
// Stageクラス
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
◇実行結果
◇解説
WebPファイルの読込部分は43行目以降のtry文の中である。ポイントとして、52行目で読み込んだWebP画像はawtのImage型(BufferedImage)であるため、55行目でJavaFXのImage型(WritableImage)に変換している。
■ WebPファイルの書出
GIF画像を読み込み、「webp-imageio」を利用して出力するサンプルプログラムを示す。
◇リソース
【使用画像】
・透過+アニメーションする画像
プロジェクト中のパス:
img/b50_r.gif
配布元:
フリー素材サイト月色すわろ
◇サンプルコード
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;
import com.luciad.imageio.webp.WebPWriteParam;
public class Main {
public static void main(String[] args)
{
try {
// 画像の読み込み
BufferedImage image = ImageIO.read(new File("img/b50_r.gif"));
// WebP画像出力
ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/webp").next();
// 出力設定
WebPWriteParam writeParam = new WebPWriteParam(writer.getLocale());
writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
writeParam.setCompressionType("Lossless");
writer.setOutput(new FileImageOutputStream(new File("img/out.webp")));
// WebP画像出力
writer.write(null, new IIOImage(image, null, null), writeParam);
} catch (IOException e) {
e.printStackTrace();
}
}
}
◇実行結果
出力ファイル:
img/out.webp
◇解説
WebPファイルの読込部分は25行目以降である。
出力結果のファイルを確認すると、「webp-imageio」では透過(アルファチャンネル)は実装できている。ただし、アニメーション出力はできていない。オプション設定等があるのかとソースを少し見てみたが、特にアニメーションの実装は見つけられなかったので、おそらく未実装な模様。