.NET TIPS

品質を指定してJPEG画像を保存するには?

デジタルアドバンテージ 遠藤 孝信
2006/12/08

 「TIPS:画像をファイルに保存するには?」では、画像ファイルをさまざまなフォーマットで保存するための方法を解説しているが、JPEG画像を保存する場合には画像の品質を指定して保存することもできる。品質を落として保存すれば当然ながら画質は悪くなるが、ファイル・サイズを小さく抑えることが可能だ。

 前掲のTIPSでは、BitmapオブジェクトをJPEGフォーマットで保存するのに、次のようにSaveメソッドの第2パラメータで「ImageFormat.Jpeg」を指定していた。

bmp.Save("pic.jpg", ImageFormat.Jpeg)

 品質を変えてJPEGフォーマットで保存するには、別のバージョンのSaveメソッドを使用して次のように行う。

bmp.Save("pic.jpg", JPEG用エンコーダ, エンコーダ用パラメータ)

 「JPEG用エンコーダ」としてはImageCodecInfoクラス(System.Drawing.Imaging名前空間)のオブジェクトを指定し、「エンコーダ用パラメータ」としてはEncoderParametersクラス(System.Drawing.Imaging名前空間)のオブジェクトを指定する。画像の品質は後者のエンコーダ用パラメータで指定する。

 以下ではJPEG用エンコーダの取得と、エンコーダ用パラメータの作成について解説する。

JPEG用エンコーダの取得

 まずはJPEG用エンコーダ(ImageCodecInfoオブジェクト)を、システムで利用可能なエンコーダの中から取得しなければならない。

 前掲のTIPSの後半で解説しているように、利用可能なエンコーダはImageCodecInfoクラスのGetImageEncodersメソッドにより列挙でき、その中からJPEG用エンコーダを選び出すコードは次のようになる。

ImageCodecInfo jpgEncoder = null; // JPEG用エンコーダ

foreach (ImageCodecInfo ici in ImageCodecInfo.GetImageEncoders()) {
  if (ici.FormatID == ImageFormat.Jpeg.Guid) {
    jpgEncoder = ici;
    break;
  }
}
Dim jpgEncoder As ImageCodecInfo = Nothing ' JPEG用エンコーダ

For Each ici As ImageCodecInfo In ImageCodecInfo.GetImageEncoders()
  If ici.FormatID = ImageFormat.Jpeg.Guid
    jpgEncoder = ici
    Exit For
  End If
Next
JPEG用エンコーダの取得

 ここでは、JPEGフォーマットを示すImageFormatオブジェクト(=ImageFormat.Jpeg)のGUIDプロパティと、各エンコーダのGUIDを示すFormatIDプロパティを比較しながらJPEG用エンコーダを選択している(ImageCodecInfoオブジェクトのMimeTypeプロパティが文字列「image/jpeg」となっているものを選択してもよい)。

エンコーダ用パラメータの作成

 品質を指定したエンコーダ用パラメータを作成するには、まずEncoderParameterクラス(System.Drawing.Imaging名前空間)のオブジェクトを作成する。

 このとき、コンストラクタの第1パラメータで「Encoder.Quality」を、第2パラメータで品質レベルを指定する。品質レベルは0〜100のInt64型の整数値で指定し、100が最高の品質となる。

Int64 quality = 20; // 品質レベル:20
EncoderParameter encParam
  = new EncoderParameter(Encoder.Quality, quality);
Dim quality As Int64 = 20 ' 品質レベル:20
Dim encParam As New EncoderParameter(Encoder.Quality, quality)
品質を指定したエンコーダ用パラメータの作成

 エンコーダ用パラメータとしては、画像の品質以外にも、色深度や輝度などを複数同時に指定可能である*。このため、Saveメソッドの第3パラメータで指定するのは、実際にはEncoderParameterオブジェクトの配列となる。

* 指定可能なパラメータの一覧については、Encoderクラス(System.Drawing.Imaging名前空間)のパブリック フィールドを参照。指定できるパラメータの種類は、使用するエンコーダによって異なる。

 EncoderParameterオブジェクトの配列用に用意されたクラスがEncoderParametersクラスである。このクラスでは、コンストラクタのパラメータで要素数を指定してインスタンス化を行う。配列の実体には、そのParamプロパティからアクセスできる。

 今回の場合には、次のようにして要素を1としてEncoderParametersオブジェクトを作成し、上記で作成したEncoderParameterオブジェクトをParamプロパティの最初の要素としてセットする。

// パラメータ用の配列の作成
EncoderParameters encParams = new EncoderParameters(1);
encParams.Param[0] = encParam;
' パラメータ用の配列の作成
Dim encParams As New EncoderParameters(1)
encParams.Param(0) = encParam
エンコーダ用パラメータの配列の作成

品質を指定してJPEG画像を保存するサンプル・プログラム

 以下に、品質を指定してJPEG画像を保存するサンプル・プログラムを示す。このサンプル・プログラムでは、JPEGファイル「test.jpg」を開き、それを品質レベル=20で「test20.jpg」というファイルに保存する

// jpgquality.cs

using System;
using System.Drawing;
using System.Drawing.Imaging;

class JpegQualityTest {
  static void Main() {

    Int64 quality = 20; // 品質レベル:20
    ImageCodecInfo jpgEncoder = null;

    // 画像のロード
    Image myImage = Image.FromFile("test.jpg");

    // JPEG用のエンコーダの取得
    foreach (ImageCodecInfo ici
          in ImageCodecInfo.GetImageEncoders()) {
      if (ici.FormatID == ImageFormat.Jpeg.Guid) {
        jpgEncoder = ici;
        break;
      }
    }

    // エンコーダに渡すパラメータの作成
    EncoderParameter encParam
      = new EncoderParameter(Encoder.Quality, quality);

    // パラメータを配列に格納
    EncoderParameters encParams = new EncoderParameters(1);
    encParams.Param[0] = encParam;

    // 画像の保存
    myImage.Save("test20.jpg", jpgEncoder, encParams);
  }
}

// コンパイル方法:csc jpgquality.cs
品質を落としてJPEG画像を保存するC#のサンプル・プログラム(jpgquality.cs)

' jpgquality.vb

Imports System
Imports System.Drawing
Imports System.Drawing.Imaging

Class JpegQualityTest
  Shared Sub Main()

    Dim quality As Int64 = 20 ' 品質レベル:20
    Dim jpgEncoder As ImageCodecInfo = Nothing

    ' 画像のロード
    Dim myImage As Image = Image.FromFile("test.jpg")

    ' JPEG用のエンコーダの取得
    For Each ici As ImageCodecInfo _
        In ImageCodecInfo.GetImageEncoders()
      If ici.FormatID = ImageFormat.Jpeg.Guid
        jpgEncoder = ici
        Exit For
      End If
    Next

    ' エンコーダに渡すパラメータの作成
    Dim encParam As New _
      EncoderParameter(Encoder.Quality, quality)

    ' パラメータを配列に格納
    Dim encParams As New EncoderParameters(1)
    encParams.Param(0) = encParam

    ' 画像の保存
    myImage.Save("test20.jpg", jpgEncoder, encParams)
  End Sub
End Class

' コンパイル方法:vbc jpgquality.vb
品質を落としてJPEG画像を保存するVBのサンプル・プログラム(jpgquality.vb)

 このサンプル・プログラムを実行するには、カレント・ディレクトリに「test.jpg」ファイルが必要となる。

 参考までに、.NET TIPSのロゴ画像を、品質レベル0、20、40、60、80、100として保存した場合の画像と、そのファイル・サイズを示しておく。

元の画像
ファイル・サイズ:6149 Bytes
品質レベル:0
ファイル・サイズ:1100 Bytes
品質レベル:20
ファイル・サイズ:2030 Bytes
品質レベル:40
ファイル・サイズ:2726 Bytes
品質レベル:60
ファイル・サイズ:3342 Bytes
品質レベル:80
ファイル・サイズ:4586 Bytes
品質レベル:100
ファイル・サイズ:13061 Bytes
品質レベルによる画像とファイル・サイズの違い

 品質レベル=100ではファイル・サイズが2倍以上になっているが、画像がスムーズになっているのが少し興味深い。End of Article

利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:クラス・ライブラリ 処理対象:ビットマップ
使用ライブラリ:ImageCodecInfoクラス(System.Drawing.Imaging名前空間)
使用ライブラリ:EncoderParametersクラス(System.Drawing.Imaging名前空間)
使用ライブラリ:EncoderParameterクラス(System.Drawing.Imaging名前空間)
使用ライブラリ:Encoderクラス(System.Drawing.Imaging名前空間)
関連TIPS:画像をファイルに保存するには?

この記事と関連性の高い別の.NET TIPS
画像をファイルに保存するには?
画像ファイルのフォーマットを知るには?
画像を読み込むには?
サムネイル画像(縮小画像)を作成するには?
画像を高品質に拡大/縮小するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間