.NET TIPS

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

デジタルアドバンテージ 一色 政彦
2009/12/24

 .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が反映されている)。End of Article

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

この記事と関連性の高い別の.NET TIPS
PictureBoxコントロールにWeb画像を表示するには?
画像ファイルを高速に読み込むには?
画像の一部の領域を切り抜くには?
画像をファイルに保存するには?
サムネイル画像(縮小画像)を作成するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム 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メールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

Insider.NET 記事ランキング

本日 月間
ソリューションFLASH