Ich lade die binären Bytes der Image-Datei-Festplatte und lade sie in ein Bitmap-Objekt. Wie finde ich den Bildtyp [JPEG, PNG, BMP usw.] vom Bitmap-Objekt?
Sieht trivial aus. Aber ich konnte es nicht verstehen!
Gibt es einen alternativen Ansatz?
Schätzen Sie Ihre Antwort.
AKTUALISIERTE RICHTIGE LÖSUNG:
@CMS: Danke für die richtige Antwort!
Beispielcode, um dies zu erreichen.
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;
}
}
Hier ist meine Erweiterungsmethode. Hoffe das hilft jemandem.
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;
}
hier ist mein Code dafür. Sie müssen zuerst das komplette Image oder den Header (die ersten 4 Bytes) in ein Byte-Array laden.
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;
}
natürlich kannst du. ImageFormat
bedeutet nicht viel. ImageCodecInfo
hat viel mehr Bedeutung.
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>
code:
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");
debug-Ausgabe:
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
Einfach gesagt, kannst du nicht. Der Grund dafür ist, dass Bitmap ein Bildtyp ist, wie JPEG, PNG usw.. Sobald Sie ein Bild in eine Bitmap laden, wird das Bild im Bitmap-Format angezeigt. Es gibt keine Möglichkeit, eine Bitmap anzusehen und die ursprüngliche Kodierung des Bildes zu verstehen (falls sich diese sogar von Bitmap unterscheidet).
Um sich nicht mit alten Themen zu beschäftigen, sondern um diese Diskussion abzuschließen, möchte ich meinen Weg zur Abfrage von allen - Bildformaten teilen, die von Windows bekannt sind.
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;
}
}
Jetzt können Sie es als Bilderweiterung verwenden, wie unten gezeigt:
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);
}
Basierend auf Alex 'Arbeit (die ich eigentlich als Lösung wähle, da es sich um eine Zeile handelt - aber ich kann noch nicht wählen, haha), habe ich die folgende Funktion für eine Bildbibliothek entwickelt
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 , Ich mochte Ihre Erweiterungsmethode und fügte eine Stringüberladung hinzu. Außerdem reduzierte ich den Code für Ihre Methode:
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);
Ein paar saubere Erweiterungsmethoden für den Typ Image
, um dies zu bestimmen, basierend auf dem obigen Fund von Alex (ImageCodecInfo.GetImageDecoders()
).
Dies ist nach dem ersten Aufruf stark optimiert, da das statische ImageCodecsDictionary im Speicher gespeichert wird (jedoch nur, nachdem es einmal verwendet wurde).
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; }
}
ein seltsames Problem, dem ich begegnete, als ich versuchte, den Mime-Typ mit imagecodeinfo zu bekommen. Bei einigen PNG-Dateien waren die Anweisungen nicht exakt gleich ...
zuerst habe ich mit ImageCodecinfo nachgefragt und wenn Code das Bildformat nicht findet, habe ich das Bildformat mit der Lösung von Matthias Wuttke verglichen.
wenn beide oben genannten Lösungen fehlschlugen, wurde die Dateimime-Art mit der Erweiterungsmethode abgerufen.
wenn sich der MIME-Typ ändert, ändert sich auch die Datei. Wir haben die Prüfsumme der heruntergeladenen Dateien so berechnet, dass sie mit der Prüfsumme der ursprünglichen Datei auf dem Server übereinstimmt.
Die einfachste Methode wurde von Cesare Imperiali wie folgt angeboten:
var format = new ImageFormat(Image.FromFile(myFile).RawFormat.Guid);
Das .ToString () für ein .jpg gibt jedoch "[ImageFormat: b96b3cae-0728-11d3-9d7b-0000f81ef32e]" anstelle von "Jpeg" zurück. Wenn dir das wichtig ist, hier ist meine Lösung:
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);