検索
連載

画像のdpi(画像解像度)を取得/設定するには?[C#、VB].NET TIPS

PC用表示 関連情報
Share
Tweet
LINE
Hatena
「.NET TIPS」のインデックス

連載目次

 .jpgファイルや.pngファイルなどの画像ファイルでは、画像のサイズとして、画素数(ピクセル数)以外にも、画像解像度(dpi:Dots Per Inch。インチ当たりのドット数)を持つ。両者とも幅と高さのそれぞれで値を持つ。

 画像解像度は画像を印刷するときなどに重要となる。例えば、画面上で幅302ピクセルの画像を、印刷時に何インチとするかを画像解像度が決定する。解像度が96dpiの画像であれば、印刷時には3.15inch(=8cm:センチ・メートル)となる(1inch=2.54cm)。また、印刷やWYSIWYGを重視する一部のアプリケーションでは、画面上でも(ピクセル数よりも)この画像解像度を重視するものがある。例えば文書作成アプリケーションのMicrosoft Wordは、画像が貼り付けられたとき、その解像度を基にWordドキュメント上での表示サイズを決定する。

 Windowsでは、ディスプレイ解像度(=画面解像度)のデフォルト値は96dpiとなっているため、例えば300dpiの画像解像度を持つ画像をWordに貼り付けると、(実際のピクセル・サイズよりも)小さいサイズで表示されてしまう。これを防ぐには、画像解像度をディスプレイ解像度と同じ、96dpiに変更する必要がある。

 次の画面は、300dpiの元画像と、それを96dpiに変更した画像を、それぞれWord上に貼り付けた例だ。


Word上に貼り付けた300dpiの画像と96dpiの画像

 このように、画像解像度の値を変更したいときがある。そこで本TIPSでは、画像解像度を取得/設定する方法を説明する。

●画像解像度を取得する方法

 まず、画像解像度を取得するには、Imageクラス(System.Drawing名前空間)のオブジェクトが持つHorizontalResolutionプロパティとVerticalResolutionプロパティを取得すればよい(取得のみで、設定はできない)。HorizontalResolutionプロパティは、水平解像度、つまり画像の幅のdpiを取得できる。VerticalResolutionプロパティは垂直解像度、つまり画像の高さのdpiを取得できる。

 ちなみにImageクラスから派生したBitmapクラス(System.Drawing名前空間)などでも同様のプロパティを利用できる。

●画像解像度を設定する方法

 次に、画像解像度を設定するには、BitmapオブジェクトのSetResolutionメソッドを用いればよい。SetResolutionメソッドの第1パラメータには水平解像度(dpi)を指定し、第2パラメータには垂直解像度を指定する。戻り値はない。

 なお、筆者が試した限り、既存の画像ファイルから作成したBitmapオブジェクトに対してSetResolutionメソッドを呼び出すと、確かに画像解像度は変更されるのだが、そのBitmapオブジェクトのSaveメソッドで画像ファイルとして保存した場合、設定した画像解像度が適用されず、元の画像解像度で保存されてしまうので、注意してほしい。設定した画像解像度で保存するには、新規にBitmapオブジェクトを作成する必要があるようだ。

●画像解像度を取得/設定するサンプル

 最後に、サンプルとして上記の画像解像度の取得/設定方法を試してみよう。次のコードは、「C:\picture.png」という画像ファイルを読み込み、画像解像度を取得する。そして、その水平解像度や垂直解像度が96dpiでなければ、同じピクセル・サイズで、かつ96dpiの画像解像度を持つBitmapオブジェクトを新規に作成し、その新しいBitmapオブジェクトに元の画像内容を描画して、「C:\picture_new.png」という名前の画像ファイルとして保存するコンソール・アプリケーションのサンプル・プログラムである。

using System;
using System.Drawing;
using System.IO;

class Program
{
  static void Main()
  {
    // 画像を読み込む
    string basePath = @"C:\picture.png";
    Bitmap bmpOrg = Bitmap.FromFile(basePath) as Bitmap;

    // 画像解像度を取得する
    float hRes = bmpOrg.HorizontalResolution;
    float vRes = bmpOrg.VerticalResolution;
    Console.WriteLine(
      "水平解像度:{0} dpi、垂直解像度:{1} dpi", hRes, vRes);

    if (hRes != 96.0F || vRes != 96.0F)
    {
      // 画像解像度を変更して新しいBitmapオブジェクトを作成
      Bitmap bmpNew = new Bitmap(bmpOrg.Width, bmpOrg.Height);
      bmpNew.SetResolution(96.0F, 96.0F);

      // 新しいBitmapオブジェクトに元の画像内容を描画
      Graphics g = Graphics.FromImage(bmpNew);
      g.DrawImage(bmpOrg, 0, 0, bmpOrg.Width, bmpOrg.Height);
      g.Dispose();

      // 画像を保存
      string dirName = Path.GetDirectoryName(basePath);
      string fileName = Path.GetFileNameWithoutExtension(basePath);
      string extName = Path.GetExtension(basePath);
      string newPath = Path.Combine(
        dirName, fileName + "_new" + extName);
      bmpNew.Save(newPath);
      bmpNew.Dispose();
      Console.WriteLine("解像度を96dpiに変更しました。");
    }

    // 画像リソースを解放
    bmpOrg.Dispose();

    // メッセージを確認できるように実行を停止
    Console.ReadKey();
  }
}

Imports System.Drawing
Imports System.IO

Module Module1

  Sub Main()

    ' 画像を読み込む
    Dim basePath = "C:\picture.png"
    Dim bmpOrg As Bitmap = Bitmap.FromFile(basePath)

    ' 画像解像度を取得する
    Dim hRes As Single = bmpOrg.HorizontalResolution
    Dim vRes As Single = bmpOrg.VerticalResolution
    Console.WriteLine( _
      "水平解像度:{0} dpi、垂直解像度:{1} dpi", hRes, vRes)

    If hRes <> 96.0F OrElse vRes <> 96.0F Then

      ' 画像解像度を変更して新しいBitmapオブジェクトを作成
      Dim bmpNew As New Bitmap(bmpOrg.Width, bmpOrg.Height)
      bmpNew.SetResolution(96.0F, 96.0F)

      ' 新しいBitmapオブジェクトに元の画像内容を描画
      Dim g As Graphics = Graphics.FromImage(bmpNew)
      g.DrawImage(bmpOrg, 0, 0, bmpOrg.Width, bmpOrg.Height)
      g.Dispose()

      ' 画像を保存
      Dim dirName = Path.GetDirectoryName(basePath)
      Dim fileName = Path.GetFileNameWithoutExtension(basePath)
      Dim extName = Path.GetExtension(basePath)
      Dim newPath = Path.Combine( _
        dirName, fileName & "_new" & extName)
      bmpNew.Save(newPath)
      bmpNew.Dispose()
      Console.WriteLine("解像度を96dpiに変更しました。")

    End If

    ' 画像リソースを解放
    bmpOrg.Dispose()

    ' メッセージを確認できるように実行を停止
    Console.ReadKey()

  End Sub

End Module

画像解像度を取得/設定するサンプル
このサンプル・アプリケーションを実行するには、System.Drawingアセンブリへの参照の追加が必要である。
保存するファイル名を決定する処理で使われているPath.GetDirectoryNameメソッドについては「TIPS:パス文字列からディレクトリ・パス部分を取り出すには?」を参照。Path.GetFileNameWithoutExtensionメソッドやPath.GetExtensionメソッドは「TIPS:パス名やファイル名からベース名と拡張子を取得するには?」を参照してほしい。「96.0f」や「96.0F」の最後にあるサフィックス「f」「F」の意味については「TIPS:数値のデータ型を明示的に指定するには?」を参照してほしい。

 このサンプルをすぐに試せるように、300dpiに設定された画像ファイルを用意した。こちらからダウンロードできる(例えばこの画像をWordにドラッグ&ドロップで貼り付けると、画像ファイルをダブルクリックしたときの画像プレビュー表示のサイズよりも、小さく表示されてしまう。ちなみにWordドキュメント印刷時の画像サイズは、画像オブジェクトの右クリック・メニューから[サイズ]を選択すると表示される[サイズ]ダイアログの[サイズと角度]で確認できる。同ダイアログの[原型のサイズ]の値はdpiが反映されている)。

カテゴリ:クラス・ライブラリ 処理対象:ビットマップ
使用ライブラリ:Imageクラス(System.Drawing名前空間)
使用ライブラリ:Bitmapクラス(System.Drawing名前空間)
関連TIPS:画像をファイルに保存するには?
関連TIPS:パス文字列からディレクトリ・パス部分を取り出すには?
関連TIPS:パス名やファイル名からベース名と拡張子を取得するには?
関連TIPS:数値のデータ型を明示的に指定するには?

「.NET TIPS」のインデックス

.NET TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

ページトップに戻る