概要
javaで画像変換を行いたいなと思い、色々と調べていたらJavaCVがメジャーぽかったので、こちらを使用することにしました。OpenCVをjava用にラッパーしたものの様です。OpenCVと言うとpythonのイメージしかなかったのですが、プログラミング言語はC++で、javaでも使えるみたいですね。
画像のフォーマットについて
画像のフォーマットは、WebP(ウェッピー)が割と新しいと言うことが分かりました。最近は、AVIFと言うのも出てきているみたいで、トレンドが速いなと思いましたが、まだ、OpenCVでは対応していないみたいです(多分)。「画像の読み込み速度は、売り上げに直結している。」みたいは記事もどこかで見かけたし、重要みたいですね。
アマゾンのページ表示速度を劇的に改善した6つの実践テクニック【SEO情報まとめ】
その他のライブラリ
image-io
WebPの変換ライブラリとして、image-ioと言うものがあり、使い方も簡単でした。自動変換とマニュアル変換の2つがあり、マニュアルでやると逆に容量が増えたので、設定は細かくやる必要がありそうです(詳しくは調べておりません)。
git
webp-imageio
OpenCV.js
一応、javascript版のOpenCV.jsと言うのもあるらしいです。ですが、これは機能が限定されているみたいで、画像のフォーマット変換には対応していないみたいでした(node.jsなら出来るみたいです)。
画像変換の際の注意点
あまり詳しくないので違っていたらゴメンナサイ。画像のフォーマットを変換する際の注意点として、jpgなどの非可逆圧縮のフォーマットは品質が保証できないかもしれません。処理的には、画像の再圧縮と言うことになるのかなと思いますが、pngやtiffと言った可逆圧縮のフォーマットであれば、問題ないかと思います。と言うか、書いててわざわざ変換までする必要はあるのかなという気もしてきた。
・png, tiff -> webp : OK
・jpb -> webP : NG?
JavaCVかOpenCVか
Javaの場合だと、JavaCVとOpenCVの2つの選択肢がありますが、mavenで見てみると、OpenCVは殆ど更新されていないみたいなので、JavaCVを使用して問題ないかと思います。
手動で設定する方法(eclipse)
eclipseで手動で設定する場合は、こちらの通りに設定すれば問題ないかと思います(動作確認済み)。一応、mavenの方が簡単なので、今回はmavenで設定しようと思います。
mavenで設定する方法
サイトで色々と書かれていますが、取り合えず、こちらの通りにすれば問題ない様です。標準的な使用であれば、設定するのは下記のみです。(昔の記事だと、javaCPPも記述しないといけないとか色々書かれていて、かなり振り回されましたが(笑)、公式サイトの通りにするのが良いようです)
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.7</version>
</dependency>
サンプルコード
こちらも、公式サイト通りに記述すれば問題ない様です。
import org.bytedeco.opencv.opencv_core.*;
import org.bytedeco.opencv.opencv_imgproc.*;
import static org.bytedeco.opencv.global.opencv_core.*;
import static org.bytedeco.opencv.global.opencv_imgproc.*;
import static org.bytedeco.opencv.global.opencv_imgcodecs.*;
public class Smoother {
public static void smooth(String filename) {
Mat image = imread(filename);
if (image != null) {
GaussianBlur(image, image, new Size(3, 3), 0);
imwrite(filename, image);
}
}
}
コードを書く時の注意点(重要)
かなりハマったので、記述しておきます。下記の様に書くとエラーになります。
//画像読み込み
Mat image = Imgcodecs.imread(filename); //Imgcodecs.追記
Imgcodecsはimreadのクラスですが、上記の様にImgcodecsを指定すると、JavaCVを通してでなく、OpenCVを直接呼び出すことになり、エラーとなります。公式サイトのサンプル通りにメソッドのみを書いて下さい。下記の様にOpenCVのクラスが自動的にimportされます。
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Size;
import org.opencv.imgcodecs.Imgcodecs; //エラーの原因(JavaCVとOpenCVが混在している)
import org.opencv.imgproc.Imgproc; //エラーの原因(JavaCVとOpenCVが混在している)
ですが、手動でJavaCVを設定した場合は、上記の様に書いても問題なく動作しました。 (何でかな?OpenCVで書いている状態だったのかな?)取り合えず、JavaCVとOpenCVをごちゃ混ぜで書くと混乱するので、JavaCVに統一して書く方が良いかと思います。
※因みにですが、JavaCVとOpenCVでは、メソッド名は同じでも引数の型が違うなど、若干の違いがあるようです。