【C++】OpenCVで実現するJPEG、PNG、WebP、AVIF画像圧縮形式の選び方と活用方法
C++でOpenCVを利用すると、JPEG、PNG、WebP、AVIFなどの画像圧縮形式が選択可能です。
JPEGは非可逆で高い品質調整ができ、PNGは可逆圧縮で劣化なく保存できます。
WebPとAVIFは圧縮性能が高く、用途に合わせた画像保存が実現されます。
JPEG形式の特徴
非可逆圧縮の仕組み
JPEGは画像のディテールの一部を削ることでデータ量を大幅に削減する方式です。
ピクセルの情報を失いながらも、目に違和感の少ないレベルを実現する点が魅力です。
目視による違いは薄く、ウェブや多くのデジタルカメラで採用される理由と言えます。
情報量とファイルサイズのバランスが優れているため、ストレージの節約や通信速度の向上に貢献します。
品質調整パラメータ
調整可能な数値と影響
JPEGではcv::imencode
関数のパラメータとして設定可能な品質数値は0から100までの範囲に調整できます。
数値が高いほど画像品質は維持され、低い数値では高い圧縮率が得られます。
たとえば、品質95ではディテールが非常に豊かに保たれる一方、品質70にするとより小さなファイルサイズが実現されます。
これによって、用途や目的に合わせた最適な品質・圧縮率の調整が可能となっています。
メリットとデメリット
高い互換性と幅広い用途
JPEGは長い歴史があり、多くのプラットフォームやアプリケーションで対応できるため、広い範囲で利用しやすいです。
- メリット
- 大部分のビューアやウェブブラウザで再生可能
- スマートフォンやデジタルカメラなど、さまざまな機器でサポートされる
- デメリット
- 非可逆圧縮なので、繰り返しの編集には不向き
- 高い圧縮率をかけるとアーティファクトが目立つことがある
PNG形式の特徴
可逆圧縮の原理
PNGは画像の各ピクセル情報を失わずに圧縮する可逆圧縮のフォーマットです。
画質の損失なく保存できるため、編集後の再利用や高品質なグラフィックスの保存に適しています。
元の画像データを正確に再現できる点が大きな強みです。
圧縮レベルの設定
数値設定と効果
PNGでの圧縮は0から9の整数設定が可能です。
設定値が高いほどデータサイズは小さくなりますが、圧縮にかかる時間も増加します。
アプリケーションに合わせて、リアルタイム性と圧縮率のバランスを見極めることが求められます。
たとえば、ウェブ配信用の画像では圧縮レベルを高く設定して容量を削減する一方、編集用画像では低い圧縮レベルを採用する方法が考えられます。
利用シーンと適用例
カラー情報保持の強み
PNGはアルファチャンネルを含む透明性の情報をそのまま保持できるため、UIデザインや図形、ロゴなどの用途で重宝されます。
- 利用シーン
- ウェブのバナーやアイコン
- アニメーションGIFの元データとして
- 高品質な図表やスクリーンショットの保存
WebP形式の特徴
可逆・非可逆圧縮の選択性
WebPは、JPEGやPNGの持つ特徴を組み合わせた柔軟なフォーマットです。
cv::imencode
を用いることで、可逆圧縮と非可逆圧縮のどちらも選択できるため、用途に合わせた最適な画像処理が実現可能です。
選択するモードにより、画質と圧縮率のバランスを自由に調整できる点が魅力です。
画質とファイルサイズの最適化
柔軟なパラメータ設定
WebPの圧縮パラメータは0~100の範囲で設定でき、品質の細かな調整が可能です。
圧縮時のパラメータを工夫することで、JPEGよりもファイルサイズを小さくしながらも、同等かそれ以上の画質を実現する場合が多く見受けられます。
たとえば、品質64で圧縮する場合、以下のコード例を参考にしてください。
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>
int main() {
// サンプル画像を作成(ここでは黒い画像を生成)
cv::Mat image = cv::Mat::zeros(480, 640, CV_8UC3);
// WebP形式で品質64に設定して圧縮する準備
std::vector<int> params = {cv::IMWRITE_WEBP_QUALITY, 64};
std::vector<uchar> buffer;
// 圧縮前の画像サイズを表示
std::cout << "圧縮前のサイズ: " << image.total() * image.elemSize()
<< " バイト" << std::endl;
// 画像をWebP形式でエンコードする
if (cv::imencode(".webp", image, buffer, params)) {
std::cout << "WebP形式で圧縮成功! 圧縮後のサイズ: " << buffer.size()
<< " バイト" << std::endl;
} else {
std::cout << "圧縮に失敗しました。" << std::endl;
}
return 0;
}
圧縮前のサイズ: 921600 バイト
WebP形式で圧縮成功! 圧縮後のサイズ: 608 バイト
対応環境の検証
利用時の注意点
利用環境によっては、WebPのサポートが古いブラウザやツールで限定されるケースがあるため、事前の動作確認が必要です。
ライブラリのバージョンやパッケージが対応しているか、実装前に確認することをおすすめします。
適用先のシステム環境との互換性をチェックすることで、後の不具合を防げます。
AVIF形式の特徴
最新規格による高圧縮率
AVIFは最新の画像規格のひとつとして注目を集めています。
先進的な圧縮技術を活用することで、非常に高い圧縮率を実現でき、同等の画質を保ちながらファイルサイズを大幅に削減できます。
理論的には、画像の構造を数学的に最適化することで、伝統的なフォーマット以上の効率を発揮する仕組みが取り入れられています。
数式で表すと、圧縮率は
という形で評価され、数値が大きいほど高い圧縮効率を意味します。
高品質と軽量化の両立
調整パラメータの概要
AVIFでは品質を0から1000までの細かな設定が可能です。
高い品質の指定をすることで細かなディテールを保持しながら、低い値に設定すれば大幅な軽量化が実現できます。
この柔軟なパラメータ設定により、用途に適した画質の調整が容易になるため、映像処理や高度なグラフィック用途においても十分活用できる設計です。
高度な画像処理との連携
利用シーンの考慮点
高度な画像解析や編集用にAVIFを採用する場合、圧縮パラメータが画像の特徴をどのように影響するかを考慮する必要があります。
- 映像コンテンツの保存や配信
- ウェブアプリケーションでのインタラクティブな画像表示
- クラウドストレージでの高効率なデータ管理
これらのケースでは、複数のパラメータ組み合わせによって、最適な画質と軽量化のバランスが実現される設計になっています。
圧縮形式選択のポイント
用途別の適合性判断
画像品質とサイズのトレードオフ
各フォーマットごとに、画質とファイルサイズのバランスは異なるため、用途に合わせた最適な形式の選択が重要です。
JPEGは一般的な写真用途、PNGはグラフィックスや透明性が必要なシーン、WebPとAVIFはさらなる軽量化を目指す場合に向いています。
ポイントは、最終的にどの程度の画質を保ちつつファイルサイズを削減できるかというトレードオフになります。
ターゲットデバイスとの互換性
最終的な利用環境でのデバイスがどのフォーマットをサポートしているか確認が必要です。
スマートフォン、タブレット、パソコン、さらにはウェブブラウザなどでの互換性確認が不可欠です。
- デスクトップ環境では、ほとんどの形式が問題なく再生できる
- モバイル機器では、処理能力やブラウザの対応状況に差が出る可能性がある
アプリケーション固有の評価基準
モバイルとデスクトップの違い
モバイル向けのアプリケーションでは、通信量やバッテリー消費を抑えるため、より高い圧縮効率が求められる場合が多いです。
一方、デスクトップ向けの用途は処理能力に余裕があるため、画質を重視した形式が選ばれることが多いです。
選択基準に合わせて、各フォーマットのメリットとデメリットを比較し、最適なパラメータ設定を選ぶことが大切です。
OpenCVにおける画像圧縮パラメータ設定
形式別パラメータオプション
JPEG品質指定の詳細
JPEGの圧縮パラメータはcv::IMWRITE_JPEG_QUALITY
を利用し、0~100の範囲で品質を設定可能です。
以下のサンプルコードは、品質95でJPEG形式に変換する例です。
#include <opencv2/opencv.hpp>
#include <vector>
#include <iostream>
int main() {
// 画像の読み込み(サンプル画像のパスを指定)
cv::Mat image = cv::imread("sample.jpg");
if (image.empty()) {
std::cout << "画像の読み込みに失敗しました。" << std::endl;
return -1;
}
// JPEG形式で品質95に設定する
std::vector<int> params = {cv::IMWRITE_JPEG_QUALITY, 95};
std::vector<uchar> buffer;
if (cv::imencode(".jpg", image, buffer, params)) {
std::cout << "JPEG圧縮成功!圧縮後のサイズ: " << buffer.size() << " バイト" << std::endl;
}
else {
std::cout << "JPEG圧縮に失敗しました。" << std::endl;
}
return 0;
}
JPEG圧縮成功!圧縮後のサイズ: XXXX バイト
PNG圧縮レベルの調整方法
PNGではcv::IMWRITE_PNG_COMPRESSION
というパラメータを用いて0から9までの圧縮レベルを指定できます。
下記のサンプルコードは、圧縮レベル3でPNG形式に変換する例です。
#include <opencv2/opencv.hpp>
#include <vector>
#include <iostream>
int main() {
cv::Mat image = cv::imread("sample.png");
if (image.empty()) {
std::cout << "画像の読み込みに失敗しました。" << std::endl;
return -1;
}
// PNGの圧縮レベル3を指定
std::vector<int> params = {cv::IMWRITE_PNG_COMPRESSION, 3};
std::vector<uchar> buffer;
if (cv::imencode(".png", image, buffer, params)) {
std::cout << "PNG圧縮成功!圧縮後のサイズ: " << buffer.size() << " バイト" << std::endl;
}
else {
std::cout << "PNG圧縮に失敗しました。" << std::endl;
}
return 0;
}
PNG圧縮成功!圧縮後のサイズ: XXXX バイト
WebP品質オプションの選択
WebPの場合、cv::IMWRITE_WEBP_QUALITY
を用いて0~100の数値で品質を設定できます。
前述のコード例で示したように、柔軟な調整が可能なため、アプリケーションの要求に応じた最適な品質が選択できます。
AVIFパラメータの調整ポイント
AVIF形式では、cv::IMWRITE_AVIF_QUALITY
によって0~1000までの品質設定が可能です。
AVIF形式をOpenCVで扱う場合、AVIF対応版ffmpegサポートを有効化してビルドする必要があります。

高い数値を指定するほどディテールが保たれ、低い数値であればさらに圧縮率が向上します。
現在のサンプルコード例は、品質512を指定した場合の利用方法の一例です。
#include <opencv2/opencv.hpp>
#include <vector>
#include <iostream>
int main() {
cv::Mat image = cv::imread("sample.jpg");
if (image.empty()) {
std::cout << "画像の読み込みに失敗しました。" << std::endl;
return -1;
}
// AVIF形式で品質512を指定して圧縮
std::vector<int> params = {cv::IMWRITE_AVIF_QUALITY, 512};
std::vector<uchar> buffer;
if (cv::imencode(".avif", image, buffer, params)) {
std::cout << "AVIF圧縮成功!圧縮後のサイズ: " << buffer.size() << " バイト" << std::endl;
}
else {
std::cout << "AVIF圧縮に失敗しました。" << std::endl;
}
return 0;
}
AVIF圧縮成功!圧縮後のサイズ: XXXX バイト
パラメータ設定時の留意点
数値設定の影響と最適化方法
各画像フォーマットにおけるパラメータは、数値の調整によって画質と圧縮率のバランスが大きく変動するため、少しずつ数値を変えて最適なポイントを見つけるとよいです。
- 数値が高い場合は、画像のディテールが保たれる分、ファイルサイズが大きくなる
- 逆に数値が低い場合、ファイルサイズは小さくなるけれども、ディテールが失われがち
これらの調整を行う際には、事前に表示環境や用途を考慮してパラメータを設定する工夫が必要です。
ソフトウェアや配信環境に合わせた最適化を図ることで、ユーザーに快適な体験を提供できます。
まとめ
各画像圧縮形式には特徴があり、用途に合わせた選択が求められます。
JPEGは広範囲で利用されやすく、PNGは編集や透明度の保持に優れています。
WebPとAVIFは最新技術を取り入れ、さらなる軽量化を実現する工夫が反映されています。
OpenCVを活用すれば、各種パラメータの細かい調整で最適な画像圧縮が実現できるため、環境や用途ごとの最適解を探してみると良いでしょう。