イメージファイルのハードドライブのバイナリバイトを読み込んで、ビットマップオブジェクトに読み込みます。ビットマップオブジェクトから画像タイプ[JPEG、PNG、BMPなど])を見つけるにはどうすればよいですか?
些細に見えます。しかし、それを理解できませんでした!
代替アプローチはありますか?
あなたの応答を感謝します。
更新された修正ソリューション:
@CMS:正しい回答をありがとう!
これを実現するサンプルコード。
using (MemoryStream imageMemStream = new MemoryStream(fileData))
{
using (Bitmap bitmap = new Bitmap(imageMemStream))
{
ImageFormat imageFormat = bitmap.RawFormat;
if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
//It's a JPEG;
else if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png))
//It's a PNG;
}
}
これが私の拡張メソッドです。これが誰かを助けることを願っています。
public static System.Drawing.Imaging.ImageFormat GetImageFormat(this System.Drawing.Image img)
{
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
return System.Drawing.Imaging.ImageFormat.Jpeg;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Bmp))
return System.Drawing.Imaging.ImageFormat.Bmp;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png))
return System.Drawing.Imaging.ImageFormat.Png;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Emf))
return System.Drawing.Imaging.ImageFormat.Emf;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Exif))
return System.Drawing.Imaging.ImageFormat.Exif;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif))
return System.Drawing.Imaging.ImageFormat.Gif;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Icon))
return System.Drawing.Imaging.ImageFormat.Icon;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.MemoryBmp))
return System.Drawing.Imaging.ImageFormat.MemoryBmp;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Tiff))
return System.Drawing.Imaging.ImageFormat.Tiff;
else
return System.Drawing.Imaging.ImageFormat.Wmf;
}
これは私のコードです。最初に、完全なイメージまたはヘッダー(最初の4バイト)をバイト配列にロードする必要があります。
public enum ImageFormat
{
Bmp,
Jpeg,
Gif,
Tiff,
Png,
Unknown
}
public static ImageFormat GetImageFormat(byte[] bytes)
{
// see http://www.mikekunz.com/image_file_header.html
var bmp = Encoding.ASCII.GetBytes("BM"); // BMP
var gif = Encoding.ASCII.GetBytes("GIF"); // GIF
var png = new byte[] { 137, 80, 78, 71 }; // PNG
var tiff = new byte[] { 73, 73, 42 }; // TIFF
var tiff2 = new byte[] { 77, 77, 42 }; // TIFF
var jpeg = new byte[] { 255, 216, 255, 224 }; // jpeg
var jpeg2 = new byte[] { 255, 216, 255, 225 }; // jpeg Canon
if (bmp.SequenceEqual(bytes.Take(bmp.Length)))
return ImageFormat.Bmp;
if (gif.SequenceEqual(bytes.Take(gif.Length)))
return ImageFormat.Gif;
if (png.SequenceEqual(bytes.Take(png.Length)))
return ImageFormat.Png;
if (tiff.SequenceEqual(bytes.Take(tiff.Length)))
return ImageFormat.Tiff;
if (tiff2.SequenceEqual(bytes.Take(tiff2.Length)))
return ImageFormat.Tiff;
if (jpeg.SequenceEqual(bytes.Take(jpeg.Length)))
return ImageFormat.Jpeg;
if (jpeg2.SequenceEqual(bytes.Take(jpeg2.Length)))
return ImageFormat.Jpeg;
return ImageFormat.Unknown;
}
もちろんできます。 ImageFormat
はあまり意味がありません。 ImageCodecInfo
にはさらに多くの意味があります。
red_dot.png
<a href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="red_dot.png" title="red_dot.png"/>
</a>
コード:
using System.Linq;
//...
//get image
var file_bytes = System.Convert.FromBase64String(@"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==");
var file_stream = new System.IO.MemoryStream(file_bytes);
var file_image = System.Drawing.Image.FromStream(file_stream);
//list image formats
var image_formats = typeof(System.Drawing.Imaging.ImageFormat).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).ToList().ConvertAll(property => property.GetValue(null, null));
System.Diagnostics.Debug.WriteLine(image_formats.Count, "image_formats");
foreach(var image_format in image_formats) {
System.Diagnostics.Debug.WriteLine(image_format, "image_formats");
}
//get image format
var file_image_format = typeof(System.Drawing.Imaging.ImageFormat).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).ToList().ConvertAll(property => property.GetValue(null, null)).Single(image_format => image_format.Equals(file_image.RawFormat));
System.Diagnostics.Debug.WriteLine(file_image_format, "file_image_format");
//list image codecs
var image_codecs = System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders().ToList();
System.Diagnostics.Debug.WriteLine(image_codecs.Count, "image_codecs");
foreach(var image_codec in image_codecs) {
System.Diagnostics.Debug.WriteLine(image_codec.CodecName + ", mime: " + image_codec.MimeType + ", extension: " + @image_codec.FilenameExtension, "image_codecs");
}
//get image codec
var file_image_format_codec = System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders().ToList().Single(image_codec => image_codec.FormatID == file_image.RawFormat.Guid);
System.Diagnostics.Debug.WriteLine(file_image_format_codec.CodecName + ", mime: " + file_image_format_codec.MimeType + ", extension: " + file_image_format_codec.FilenameExtension, "image_codecs", "file_image_format_type");
デバッグ出力:
image_formats: 10
image_formats: MemoryBMP
image_formats: Bmp
image_formats: Emf
image_formats: Wmf
image_formats: Gif
image_formats: Jpeg
image_formats: Png
image_formats: Tiff
image_formats: Exif
image_formats: Icon
file_image_format: Png
image_codecs: 8
image_codecs: Built-in BMP Codec, mime: image/bmp, extension: *.BMP;*.DIB;*.RLE
image_codecs: Built-in JPEG Codec, mime: image/jpeg, extension: *.JPG;*.JPEG;*.JPE;*.JFIF
image_codecs: Built-in GIF Codec, mime: image/gif, extension: *.GIF
image_codecs: Built-in EMF Codec, mime: image/x-emf, extension: *.EMF
image_codecs: Built-in WMF Codec, mime: image/x-wmf, extension: *.WMF
image_codecs: Built-in TIFF Codec, mime: image/tiff, extension: *.TIF;*.TIFF
image_codecs: Built-in PNG Codec, mime: image/png, extension: *.PNG
image_codecs: Built-in ICO Codec, mime: image/x-icon, extension: *.ICO
Built-in PNG Codec, mime: image/png, extension: *.PNG
単に話すことはできません。理由は、ビットマップがJPEG、PNGなどと同じように画像の一種であるためです。画像をビットマップにロードしたら、ビットマップ形式の画像を読み込みます。ビットマップを見て、画像の元のエンコードを理解する方法はありません(ビットマップと異なる場合でも)。
古いトピックを気にすることはありませんが、この議論を完了するために、Windowsで知られているall画像形式を照会する方法を共有したいと思います。
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
public static class ImageExtentions
{
public static ImageCodecInfo GetCodecInfo(this System.Drawing.Image img)
{
ImageCodecInfo[] decoders = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo decoder in decoders)
if (img.RawFormat.Guid == decoder.FormatID)
return decoder;
return null;
}
}
以下に示すように、これを画像の拡張子として使用できます。
public void Test(Image img)
{
ImageCodecInfo info = img.GetCodecInfo();
if (info == null)
Trace.TraceError("Image format is unkown");
else
Trace.TraceInformation("Image format is " + info.FormatDescription);
}
上記のアレックスの作業に基づいて(1行なので実際に解決策として投票しますが、まだ投票できませんが)、画像ライブラリ用に次の関数を考え出しました。 4.0が必要です
Public Enum Formats
Unknown
Bmp
Emf
Wmf
Gif
Jpeg
Png
Tiff
Icon
End Enum
Public Shared Function ImageFormat(ByVal Image As System.Drawing.Image) As Formats
If Not System.Enum.TryParse(Of Formats)(System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders().ToList().[Single](Function(ImageCodecInfo) ImageCodecInfo.FormatID = Image.RawFormat.Guid).FormatDescription, True, ImageFormat) Then
Return Formats.Unknown
End If
End Function
Agent CK 、拡張メソッドが好きで、文字列のオーバーロードを追加し、さらにメソッドのコードを減らしました:
public static class ImageExtentions
{
public static ImageCodecInfo GetCodecInfo(this Image img) =>
ImageCodecInfo.GetImageDecoders().FirstOrDefault(decoder => decoder.FormatID == img.RawFormat.Guid);
// Note: this will throw an exception if "file" is not an Image file
// quick fix is a try/catch, but there are more sophisticated methods
public static ImageCodecInfo GetCodecInfo(this string file)
{
using (var img = Image.FromFile(file))
return img.GetCodecInfo();
}
}
// Usage:
string file = @"C:\MyImage.tif";
string description = $"Image format is {file.GetCodecInfo()?.FormatDescription ?? "unknown"}.";
Console.WriteLine(description);
上記のAlexによる検索(ImageCodecInfo.GetImageDecoders()
)に基づいて、これを決定するためのImage
型のいくつかのクリーンな拡張メソッド。
これは、静的ImageCodecsDictionaryがメモリに保存されるため、最初の呼び出し後に高度に最適化されます(ただし、一度使用された後のみ)。
public static class ImageCodecInfoX
{
private static Dictionary<Guid, ImageCodecInfoFull> _imageCodecsDictionary;
public static Dictionary<Guid, ImageCodecInfoFull> ImageCodecsDictionary
{
get
{
if (_imageCodecsDictionary == null) {
_imageCodecsDictionary =
ImageCodecInfo.GetImageDecoders()
.Select(i => {
var format = ImageFormats.Unknown;
switch (i.FormatDescription.ToLower()) {
case "jpeg": format = ImageFormats.Jpeg; break;
case "png": format = ImageFormats.Png; break;
case "icon": format = ImageFormats.Icon; break;
case "gif": format = ImageFormats.Gif; break;
case "bmp": format = ImageFormats.Bmp; break;
case "tiff": format = ImageFormats.Tiff; break;
case "emf": format = ImageFormats.Emf; break;
case "wmf": format = ImageFormats.Wmf; break;
}
return new ImageCodecInfoFull(i) { Format = format };
})
.ToDictionary(c => c.CodecInfo.FormatID);
}
return _imageCodecsDictionary;
}
}
public static ImageCodecInfoFull CodecInfo(this Image image)
{
ImageCodecInfoFull codecInfo = null;
if (!ImageCodecsDictionary.TryGetValue(image.RawFormat.Guid, out codecInfo))
return null;
return codecInfo;
}
public static ImageFormats Format(this Image image)
{
var codec = image.CodecInfo();
return codec == null ? ImageFormats.Unknown : codec.Format;
}
}
public enum ImageFormats { Jpeg, Png, Icon, Gif, Bmp, Emf, Wmf, Tiff, Unknown }
/// <summary>
/// Couples ImageCodecInfo with an ImageFormats type.
/// </summary>
public class ImageCodecInfoFull
{
public ImageCodecInfoFull(ImageCodecInfo codecInfo = null)
{
Format = ImageFormats.Unknown;
CodecInfo = codecInfo;
}
public ImageCodecInfo CodecInfo { get; set; }
public ImageFormats Format { get; set; }
}
imagecodeinfoを使用してMIMEタイプを取得しようとしたときに直面した1つの奇妙な問題..いくつかのpngファイルでは、GUIDがまったく同じではありませんでした...
最初にImageCodecinfoでチェックしていましたが、コードがimageformatを見つけられない場合は、Matthias Wuttkeのソリューションを使用してimageformatを比較しました。
上記の解決策の両方が失敗した場合、ファイルmimeタイプを取得するために拡張メソッドを使用しました。
mIMEタイプが変更されるとファイルも変更される場合、サーバー上の元のファイルのチェックサムと一致するようにダウンロードされたファイルのチェックサムを計算していました..適切なファイルを出力として取得することが重要でした。
Cesare Imperiali が提供する最も簡単な方法は次のとおりです。
var format = new ImageFormat(Image.FromFile(myFile).RawFormat.Guid);
ただし、.jpgの.ToString()は、「Jpeg」ではなく「[ImageFormat:b96b3cae-0728-11d3-9d7b-0000f81ef32e]」を返します。それがあなたにとって重要な場合、ここに私の解決策があります:
public static class ImageFilesHelper
{
public static List<ImageFormat> ImageFormats =>
typeof(ImageFormat).GetProperties(BindingFlags.Static | BindingFlags.Public)
.Select(p => (ImageFormat)p.GetValue(null, null)).ToList();
public static ImageFormat ImageFormatFromRawFormat(ImageFormat raw) =>
ImageFormats.FirstOrDefault(f => raw.Equals(f)) ?? ImageFormat.Bmp;
}
// usage:
var format = ImageFilesHelper.ImageFormatFromRawFormat(Image.FromFile(myFile).RawFormat);