メソッド | 読み込み元 |
---|---|
FromFile(String) | ファイル |
FromStream(Stream) | ストリーム |
FromHbitmap(IntPtr) | GDIビットマップ ハンドル |
Bitmapのコンストラクタからも生成できます。c# - Difference between Bitmap.FromFile(path) and new Bitmap(path) - Stack Overflow
ファイルからImageを作成できます。ストリームから読み込む必要がないならば、こちらのメソッドを用いた方が高速です。
public static System.Drawing.Image FromFile ( string filename, bool useEmbeddedColorManagement );FromFile(String, Boolean) - Image.FromFile メソッド (System.Drawing) | Microsoft Learn
useEmbeddedColorManagementをtrueとすると、画像ファイルに埋め込まれている色管理情報 (color management information) に従い、色補正 (color correction) が適用されます。この情報には、ICCプロファイル、ガンマ値、色度 (chromaticity) 情報を含めることができます。
このuseEmbeddedColorManagementを省略すると、falseが指定されます。FromFile - Image.cs
Image image = Image.FromFile("sample.bmp"); Graphics g = e.Graphics; g.DrawImage(image, 0, 0);
不正な画像ファイルから読み込むと、「メモリが不足しています。」としてOutOfMemoryExceptionが投げられます。
string filename = "sample.jpg";
new FileStream(filename, FileMode.Create);
Image.FromFile(filename); // OutOfMemoryException
ストリームからImageを作成できます。
public static System.Drawing.Image FromStream ( System.IO.Stream stream, // bool useEmbeddedColorManagement, // trueならば、ストリームに埋め込まれている色管理情報を使用する bool validateImageData // trueならば、イメージ データを検証する );FromStream(Stream, Boolean, Boolean) - Image.FromStream メソッド (System.Drawing) | Microsoft Learn
useEmbeddedColorManagementとvalidateImageDataがないオーバーロードでは、それぞれfalseとtrueが指定されます。validateImageDataをtrueとしたときはGdip.GdipImageForceValidation()が呼ばれ、それがGdip.Okでなければ例外が発生します。FromStream - Image.cs
不正なストリームから読み込むと、「使用されたパラメーターが有効ではありません。」としてArgumentExceptionが投げられます。
ストリームからImageを作成したときは、そのImageが有効な間はストリームを閉じてはなりません。閉じてしまうと保存時に「GDI+ で汎用エラーが発生しました。 (A generic error occurred in GDI+.)」としてExternalExceptionが発生します。c# - Image.Save(..) throws a GDI+ exception because the memory stream is closed - Stack Overflow
Image image; using (FileStream fs = new FileStream("sample1.bmp", FileMode.Open, FileAccess.Read)) { image = Image.FromStream(fs); } image.Save("sample2.bmp"); // ExternalExceptionが発生
このことはドキュメントに記載されています。
You must keep the stream open for the lifetime of the Image.
FromStream(Stream) - Image.FromStream Method (System.Drawing) | Microsoft Learn
よってストリームをすぐに閉じる必要があるときは、他のImageに複製します。
Image image; using (FileStream fs = new FileStream("sample1.bmp", FileMode.Open, FileAccess.Read)) using (Image temp = Image.FromStream(fs)) { image = new Bitmap(temp); }
Image image; using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) using (MemoryStream ms = new MemoryStream()) { await fs.CopyToAsync(ms); using (Image temp = Image.FromStream(ms)) { image = new Bitmap(temp); } }
画像のメタデータを取得するだけならば、validateImageDataをfalseとしてイメージ データの検証を省くことで処理時間を短縮できます。 画像ファイルを高速に読み込むには?[2.0のみ、C#、VB] - @IT 遠藤孝信 (2007/05/24) c# - Getting image dimensions without reading the entire file - Stack Overflow
public static System.Drawing.Bitmap FromHbitmap ( IntPtr hbitmap, IntPtr hpalette );Image.FromHbitmap Method (System.Drawing) | Microsoft Learn
GDIパレットへのハンドルを省略すると、IntPtr.Zeroが渡されます。FromHbitmap - Image.cs
このメソッドではGDIビットマップのコピーが作成されるため、新しいビットマップの作成後にコピー元のビットマップを解放できます。FromHbitmap(IntPtr) - Image.FromHbitmap Method (System.Drawing) | Microsoft Learn
Bitmap bitmap = new Bitmap("sample.bmp"); IntPtr hBitmap = bitmap.GetHbitmap(); Bitmap newBitmap = Image.FromHbitmap(hBitmap); DeleteObject(hBitmap);
このときDeleteObject()は、Win32のDeleteObject()です。
[DllImport("gdi32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DeleteObject(IntPtr hObject);
Imageクラスとしては新規に作成できないため、このクラスを継承したBitmapとして作成します。
Bitmap bitmap = new Bitmap(100, 100); Graphics g = Graphics.FromImage(bitmap); g.DrawLine(Pens.Red, 0, 0, 10, 10);
Graphics.FromImage()からGraphicsを取得することで、Imageに描画することもできます。c# - how to draw a line on a image? - Stack Overflow
型 | プロパティ | 内容 |
---|---|---|
int | Width | ピクセル単位の幅 |
int | Height | ピクセル単位の高さ |
Size | Size | ピクセル単位のサイズ。WidthとHeightプロパティから取得するのと等しい Size - Image.cs |
SizeF | PhysicalDimension | 画像の幅と高さ。Bitmapならばピクセル単位、Metafileならば0.01mm単位 |
float | HorizontalResolution | 水平方向の解像度 |
float | VerticalResolution | 垂直方向の解像度 |
int | Flags | ピクセル データの属性フラグ。ImageFlags列挙型のビットの合計値 |
ImageFormat | RawFormat | ファイル形式 |
PixelFormat | PixelFormat | ピクセル形式 |
ColorPalette | Palette | 使用されているカラーパレット |
int[] | PropertyIdList | このImageに格納されている、すべてのID |
PropertyItem[] | PropertyItems | このImageに格納されている、すべてのプロパティ |
このプロパティから得られるImageFormatクラスのGuidプロパティは下表の値となっており、先頭から7~8文字だけが異なっています。
形式 | プロパティ | Guidの値 ※1 |
---|---|---|
Windows BMP format | Bmp | b96b3cab-0728-11d3-9d7b-0000f81ef32e |
Emf | b96b3cac-0728-11d3-9d7b-0000f81ef32e | |
Exif | b96b3cb2-0728-11d3-9d7b-0000f81ef32e | |
GIF format | Gif | b96b3cb0-0728-11d3-9d7b-0000f81ef32e |
Icon | b96b3cb5-0728-11d3-9d7b-0000f81ef32e | |
JPEG format | Jpeg | b96b3cae-0728-11d3-9d7b-0000f81ef32e |
MemoryBMP | b96b3caa-0728-11d3-9d7b-0000f81ef32e | |
PNG format | Png | b96b3caf-0728-11d3-9d7b-0000f81ef32e |
TIFF format | Tiff | b96b3cb1-0728-11d3-9d7b-0000f81ef32e |
Wmf | b96b3cad-0728-11d3-9d7b-0000f81ef32e |
Console.WriteLine(ImageFormat.Bmp.Guid);
のようにして取得
列挙子 | 10進 | 16進 | 内容 |
---|---|---|---|
DontCare | 0 | 0x000000 | No pixel format is specified. |
Undefined | 0 | 0x000000 | The pixel format is undefined. |
Max | 15 | 0x00000F | The maximum value for this enumeration. |
Indexed | 65536 | 0x010000 | The pixel data contains color-indexed values, which means the values are an index to colors in the system color table, as opposed to individual color values. |
Gdi | 131072 | 0x020000 | The pixel data contains GDI colors. |
Format16bppRgb555 | 135173 | 0x021005 | Specifies that the format is 16 bits per pixel; 5 bits each are used for the red, green, and blue components. The remaining bit is not used. |
Format16bppRgb565 | 135174 | 0x021006 | Specifies that the format is 16 bits per pixel; 5 bits are used for the red component, 6 bits are used for the green component, and 5 bits are used for the blue component. |
Format24bppRgb | 137224 | 0x021808 | Specifies that the format is 24 bits per pixel; 8 bits each are used for the red, green, and blue components. |
Format32bppRgb | 139273 | 0x022009 | Specifies that the format is 32 bits per pixel; 8 bits each are used for the red, green, and blue components. The remaining 8 bits are not used. |
Format1bppIndexed | 196865 | 0x030101 | Specifies that the pixel format is 1 bit per pixel and that it uses indexed color. The color table therefore has two colors in it. |
Format4bppIndexed | 197634 | 0x030402 | Specifies that the format is 4 bits per pixel, indexed. |
Format8bppIndexed | 198659 | 0x030803 | Specifies that the format is 8 bits per pixel, indexed. The color table therefore has 256 colors in it. |
Alpha | 262144 | 0x040000 | The pixel data contains alpha values that are not premultiplied. |
Format16bppArgb1555 | 397319 | 0x061007 | The pixel format is 16 bits per pixel. The color information specifies 32,768 shades of color, of which 5 bits are red, 5 bits are green, 5 bits are blue, and 1 bit is alpha. |
PAlpha | 524288 | 0x080000 | The pixel format contains premultiplied alpha values. |
Format32bppPArgb | 925707 | 0x0E200B | Specifies that the format is 32 bits per pixel; 8 bits each are used for the alpha, red, green, and blue components. The red, green, and blue components are premultiplied, according to the alpha component. |
Extended | 1048576 | 0x100000 | Reserved. |
Format16bppGrayScale | 1052676 | 0x101004 | The pixel format is 16 bits per pixel. The color information specifies 65536 shades of gray. |
Format48bppRgb | 1060876 | 0x10300C | Specifies that the format is 48 bits per pixel; 16 bits each are used for the red, green, and blue components. |
Format64bppPArgb | 1851406 | 0x1C400E | Specifies that the format is 64 bits per pixel; 16 bits each are used for the alpha, red, green, and blue components. The red, green, and blue components are premultiplied according to the alpha component. |
Canonical | 2097152 | 0x200000 | The default pixel format of 32 bits per pixel. The format specifies 24-bit color depth and an 8-bit alpha channel. |
Format32bppArgb | 2498570 | 0x26200A | Specifies that the format is 32 bits per pixel; 8 bits each are used for the alpha, red, green, and blue components. |
Format64bppArgb | 3424269 | 0x34400D | Specifies that the format is 64 bits per pixel; 16 bits each are used for the alpha, red, green, and blue components. |
イメージを回転、反転、またはそれを同時に行えます。
public void RotateFlip( RotateFlipType rotateFlipType )Image.RotateFlip メソッド (RotateFlipType) (System.Drawing) | MSDN
一方でイメージの拡大/縮小は、大きさを指定してBitmapのコンストラクタを呼ぶことで行えます。
イメージを保存できます。
public void Save (string filename);Save(String) - Image.Save メソッド (System.Drawing) | Microsoft Learn
Image image = Image.FromFile("sample1.bmp"); image.Save("sample2.bmp");
filenameにファイルが存在していた場合には、上書きされます。次のような理由で保存できなかったときは、ExternalExceptionが投げられます。
Imageのコピーを作成できます。
public object Clone ();Image.Clone メソッド (System.Drawing) | Microsoft Learn
ピクセル データへの参照がコピーされるだけで、それは元のImageと共有されます。 c# - What's the difference between Bitmap.Clone() and new Bitmap(Bitmap)? - Stack Overflow Clone - Image.cs
Clone()で作成したコピーと元のImageに対して異なるスレッドから同時にアクセスされると、0xC0000005 (アクセス違反) や0xc0000374 (ヒープ破損) が発生します。
Imageのサムネイルを取得できます。
public System.Drawing.Image GetThumbnailImage ( int thumbWidth, int thumbHeight, System.Drawing.Image.GetThumbnailImageAbort callback, // デリゲートの参照を渡す。しかし使用されない IntPtr callbackData // IntPtr.Zeroを渡す );Image.GetThumbnailImage メソッド (System.Drawing) | Microsoft Learn
このメソッドは埋め込みサムネイルがあったならばそれが、なければメイン画像が指定のサイズに調整されます。120x120のサイズを指定するのが最適なため、それを超えるならば DrawImage()でサイズを調整します。Remarks - Image.GetThumbnailImage Method (System.Drawing) | Microsoft Learn
サムネイル画像(縮小画像)を作成するには?[C#、VB] - @IT 遠藤孝信 (2007/02/22)型 | プロパティ | 内容 |
---|---|---|
int[] | PropertyIdList | このImageに格納されている、すべてのID |
PropertyItem[] | PropertyItems | このImageに格納されている、すべてのプロパティ |
メソッド | 機能 |
---|---|
SetPropertyItem(PropertyItem) | PropertyItemをImageに格納できる |
GetPropertyItem(Int32) | プロパティのID指定して、プロパティを取得できる |
RemovePropertyItem(Int32) | プロパティのID指定して、プロパティを除去できる |
ImageのPropertyItemsプロパティから、Imageに含まれるメタデータを取得できます。その内容はPropertyItemクラスのTypeによって異なるため、その値を元にValueを解釈します。方法 : イメージ メタデータを読み取る - Windows Forms | Microsoft Learn
FileStream fs = new FileStream("sample.jpg", FileMode.Open, FileAccess.Read); Image image = Image.FromStream(fs, false, false); const int PropertyTagImageDescription = 0x010E; int index = Array.IndexOf(image.PropertyIdList, PropertyTagImageDescription); if (index != -1) { PropertyItem propertyItem = image.PropertyItems[index]; string text = Encoding.ASCII.GetString(propertyItem.Value); }
指定のプロパティから取得するにはGetPropertyItem()がありますが、それがサポートされていないと例外が投げられます。
try { const int PropertyTagImageDescription = 0x010E; PropertyItem propertyItem = image.GetPropertyItem(PropertyTagImageDescription); string text = Encoding.ASCII.GetString(propertyItem.Value); } catch (ArgumentException e) { }
PropertyItem.Idプロパティの値とその意味は、Property Item Descriptionsで一覧できます。
名前 | タグ名 ※1 | PropertyItem.Id プロパティの値 | データ型 | エクスプローラでの表示名 |
---|---|---|---|---|
PropertyTagImageDescription | ImageDescription | 0x010E | PropertyTagTypeASCII | タイトル (Title) |
XPTitle | 0x9C9B | PropertyTagTypeByte (Unicode) | タイトル (Title) | |
XPComment | 0x9C9C | PropertyTagTypeByte (Unicode) | コメント (Comments) | |
XPKeywords | 0x9C9E | PropertyTagTypeByte (Unicode) | タグ (Tsgs) | |
XPSubject | 0x9C9F | PropertyTagTypeByte (Unicode) | 件名 (Subject) |
データ型を表すPropertyItem.Typeは数値で表されますが、その意味は下表の通りであり、その詳細はImage property tag type constantsにあります。
値 | データ型 |
---|---|
1 | PropertyTagTypeByte |
2 | PropertyTagTypeASCII |
3 | PropertyTagTypeShort |
4 | PropertyTagTypeLong |
5 | PropertyTagTypeRational |
7 | PropertyTagTypeUndefined |
9 | PropertyTagTypeSLONG |
10 | PropertyTagTypeSRational |
Image.SetPropertyItem()でメタデータを書き込めますが、その引数に必要なPropertyItemクラスを生成する手段が提供されていないため、メタデータを有する既存のファイルから取得してくる必要があります。Remarks - Image.SetPropertyItem(PropertyItem) Method (System.Drawing) | Microsoft Learn
Image image = Image.FromFile("sample.jpg"); byte[] bytes = Encoding.ASCII.GetBytes("ABC\0"); const int PropertyTagImageDescription = 0x010E; PropertyItem propertyItem = image.GetPropertyItem(PropertyTagImageDescription); propertyItem.Value = bytes; propertyItem.Len = bytes.Length; image.SetPropertyItem(propertyItem);
またはGetConstructor()を用いてPropertyItemのインスタンスを生成する方法もあります。
Type type = typeof(PropertyItem); ConstructorInfo constructorInfo = type.GetConstructor( BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null); PropertyItem propertyItem = (PropertyItem)constructorInfo.Invoke(null); const int PropertyTagImageDescription = 0x010E; const short PropertyTagTypeASCII = 2; byte[] bytes = Encoding.ASCII.GetBytes("ABC\0"); propertyItem.Id = PropertyTagImageDescription; propertyItem.Type = PropertyTagTypeASCII; propertyItem.Value = bytes; propertyItem.Len = bytes.Length;
SetPropertyItem()でメタデータを書き込むとき、異なるスレッドからGraphics.DrawImage()などでImageがアクセスされないようにします。さもなくばArgumentException例外が投げられます。
同一のImageに対して複数のスレッドからアクセスすると、「オブジェクトは現在他の場所で使用されています。 (Object is currently in use elsewhere.)」としてInvalidOperationExceptionが投げられます。よってそのような場所ではlockで同期させるか、Clone()で複製を作ることで同一のオブジェクトとならないようにします。なおClone()もスレッドセーフではないため、これの呼び出しも同期させる必要があります。c# - InvalidOperationException - object is currently in use elsewhere - Stack Overflow