Cv2.ImWrite の使い方【OpenCV/C#】〜画像をファイルに保存する〜

OpenCV for C#
📌 準備: OpenCV の環境構築がまだの方はこちら → C++ 環境構築ガイドC#(OpenCvSharp)セットアップ

Cv2.ImWrite の使い方【OpenCV/C#】〜画像をファイルに保存する〜

Cv2.ImWrite は、Mat オブジェクトを PNG・JPEG・BMP などの画像ファイルとして保存する関数です。拡張子を変えるだけでフォーマットが切り替わり、保存オプションで品質や圧縮率も制御できます。

最小の呼び出しはこれだけです。

bool ok = Cv2.ImWrite("output.png", mat);

動作環境

項目 バージョン
OpenCV(OpenCvSharp4) 4.x 系
.NET 8.0
NuGet OpenCvSharp4 / OpenCvSharp4.runtime.win(Windows実行時)
dotnet add package OpenCvSharp4
dotnet add package OpenCvSharp4.runtime.win

基本の使い方

using OpenCvSharp;

// 読み込んだ画像をそのまま別フォーマットで保存する
using var src = Cv2.ImRead("input.jpg", ImreadModes.Color);
if (src.Empty())
{
    Console.WriteLine("画像の読み込みに失敗しました。");
    return;
}

// PNG として保存(戻り値で成否を確認)
bool success = Cv2.ImWrite("output.png", src);
Console.WriteLine(success ? "保存成功" : "保存失敗");

実行すると、カレントディレクトリに output.png が生成され、コンソールに以下が表示されます。

保存成功

各行のポイント

  • Cv2.ImRead で読み込んだ Mat をそのまま渡せます。using による解放を忘れずに行います。
  • 第1引数のファイルパスに指定した拡張子がフォーマットを決定します(コーデック指定は不要)。
  • 戻り値は bool で、false の場合はパスの書き込み権限不足やサポート外フォーマットが原因です。

引数と戻り値

bool Cv2.ImWrite(string fileName, Mat img, int[]? prms = null)
引数 説明
fileName string 保存先のファイルパス。拡張子でフォーマットを決定する
img Mat 保存する画像データ
prms int[]? 保存オプション(後述)。省略時はデフォルト設定

戻り値: bool — 保存成功で true、失敗で false

主な保存オプション(prms に渡す定数)

定数(ImwriteFlags 値の範囲 説明
ImwriteFlags.JpegQuality 0〜100 JPEG 品質(デフォルト 95)
ImwriteFlags.PngCompression 0〜9 PNG 圧縮レベル(デフォルト 3)
ImwriteFlags.WebpQuality 1〜100 WebP 品質

prms[定数, 値, 定数, 値, ...] の順で並べた int[] として渡します。

実践例

JPEG 品質を指定して保存

ファイルサイズを抑えたい場面でよく使います。品質値を下げるほどファイルサイズが小さくなりますが、圧縮アーティファクトが増えます。

using OpenCvSharp;

using var src = Cv2.ImRead("input.png", ImreadModes.Color);
if (src.Empty())
{
    Console.WriteLine("画像の読み込みに失敗しました。");
    return;
}

// JPEG 品質 75 で保存
int[] jpegParams =
[
    (int)ImwriteFlags.JpegQuality, 75
];
bool success = Cv2.ImWrite("output_q75.jpg", src, jpegParams);
Console.WriteLine(success ? "JPEG 保存成功" : "JPEG 保存失敗");

PNG 圧縮レベルを指定して保存

PNG はロスレスなので品質は変わりませんが、圧縮レベルで保存速度とファイルサイズのトレードオフを調整できます。0(無圧縮・高速)〜9(最高圧縮・低速)です。

using OpenCvSharp;

using var src = Cv2.ImRead("input.jpg", ImreadModes.Color);
if (src.Empty())
{
    Console.WriteLine("画像の読み込みに失敗しました。");
    return;
}

// PNG 圧縮レベル 6 で保存
int[] pngParams =
[
    (int)ImwriteFlags.PngCompression, 6
];
bool success = Cv2.ImWrite("output_c6.png", src, pngParams);
Console.WriteLine(success ? "PNG 保存成功" : "PNG 保存失敗");

グレースケール変換して保存

前処理後の中間画像をデバッグ目的でダンプしたい場面でも ImWrite はそのまま使えます。

using OpenCvSharp;

using var src = Cv2.ImRead("input.jpg", ImreadModes.Color);
if (src.Empty())
{
    Console.WriteLine("画像の読み込みに失敗しました。");
    return;
}

// グレースケール変換
using var gray = new Mat();
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);

bool success = Cv2.ImWrite("output_gray.png", gray);
Console.WriteLine(success ? "グレースケール保存成功" : "保存失敗");

実行すると output_gray.png にグレースケール画像が保存されます。

グレースケール保存成功

つまずきポイント

⚠️ 戻り値の false を無視してしまう

ImWrite はディレクトリが存在しない・書き込み権限がない場合でも例外を投げず false を返すだけです。保存の成否を確実に確認する習慣をつけましょう。保存先ディレクトリが存在しない場合は事前に Directory.CreateDirectory で作成してください。

// NG: 戻り値を捨てている
Cv2.ImWrite("results/output.png", mat);

// OK: 戻り値を確認する
bool ok = Cv2.ImWrite("results/output.png", mat);
if (!ok) throw new IOException("画像の保存に失敗しました。");

⚠️ 日本語パスが通らない場合がある

Windows 環境によっては、日本語を含むファイルパスで保存に失敗することがあります(OpenCV 4.x 時点)。この場合は Cv2.ImEncode でバイト配列に変換してから File.WriteAllBytes で書き出す回避策が有効です。

Cv2.ImEncode(".png", mat, out byte[] buf);
File.WriteAllBytes("出力/画像.png", buf);

⚠️ Mat の Dispose 漏れに注意

ImWrite に渡した Mat は保存が終わっても自動解放されません。using ブロックで確実に Dispose を呼ぶことで、ネイティブメモリのリークを防いでください。本記事のサンプルはすべて using var で対応しています。

関連する関数

  • Cv2.ImReadImWrite と対になる読み込み関数。セットで使うことが多い
  • Cv2.ImEncode — ファイルに書かずメモリ上のバイト配列に符号化する。日本語パス回避にも使える
  • Cv2.ImDecode — バイト配列から Mat を復元する。ImEncode の逆操作
  • Cv2.CvtColor — 保存前のカラー空間変換に使用

まとめ

Cv2.ImWrite は拡張子でフォーマットを自動判定し、int[] の保存オプションで品質・圧縮率を細かく制御できます。戻り値の bool で必ず保存成否を確認し、日本語パスが絡む場合は Cv2.ImEncode + File.WriteAllBytes の組み合わせで回避しましょう。

🛠 画像処理のプロが開発するSDK/API

本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/APIを開発しています。SDK は C#/.NET 8 に正式対応しており、OpenCvSharp を使うプロジェクトからそのまま組み込めます。

→ なりすまし判定SDK/APIの詳細を見る
→ API仕様書・サンプルコード

タイトルとURLをコピーしました