Получить ImageFormat из System.Drawing.Image.RawFormat

Этот код не работает при попытке вызвать Image.Save(MemoryStream, ImageFormat).

Я получаю исключение:

Значение не может быть null.Parameter name: encoder "

ImageFormat format = generatedImage.RawFormat as ImageFormat;
image.ImageData = generatedImage.Save(format);

Он работает, если я передаю объект ImageFormat непосредственно, например. ImageFormat.Jpeg.

Каков наилучший способ преобразования rawformat в ImageFormat (в идеале без оператора switch или много операторов if)

Спасибо Бен

Ответ 1

Я использую следующий метод hepler для этого:

public static string GetMimeType(Image i)
{
    var imgguid = i.RawFormat.Guid;
    foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageDecoders()) 
    {
        if (codec.FormatID == imgguid)
            return codec.MimeType;
    }
    return "image/unknown";
}

Ответ 2

Извините, я не нашел возможности напрямую извлечь "правильный" ImageFormat из обработанного или сгенерированного объекта Image.

Это мой код, вы можете принять его, сохранив статический элемент ImageFormat вместо типа mimetype.

                if (image.RawFormat.Equals(ImageFormat.Jpeg))
                    binary.MetaInfo.Mimetype = "image/jpeg";
                else if (image.RawFormat.Equals(ImageFormat.Bmp))
                    binary.MetaInfo.Mimetype = "image/bmp";
                else if (image.RawFormat.Equals(ImageFormat.Emf))
                    binary.MetaInfo.Mimetype = "image/emf";
                else if (image.RawFormat.Equals(ImageFormat.Exif))
                    binary.MetaInfo.Mimetype = "image/exif";
                else if (image.RawFormat.Equals(ImageFormat.Gif))
                    binary.MetaInfo.Mimetype = "image/gif";
                else if (image.RawFormat.Equals(ImageFormat.Icon))
                    binary.MetaInfo.Mimetype = "image/icon";
                else if (image.RawFormat.Equals(ImageFormat.Png))
                    binary.MetaInfo.Mimetype = "image/png";
                else if (image.RawFormat.Equals(ImageFormat.Tiff))
                    binary.MetaInfo.Mimetype = "image/tiff";
                else if (image.RawFormat.Equals(ImageFormat.Wmf))
                    binary.MetaInfo.Mimetype = "image/wmf";

Вы можете привести его в порядок, используя массив статических элементов ImageFormat, но я думаю, что вы не сможете избежать переключения или цикла.

С наилучшими пожеланиями, Маттиас

Ответ 3

Вы ищете это?


System.Drawing.Imaging.ImageFormat fmt = new System.Drawing.Imaging.ImageFormat(generatedImage.RawFormat.Guid);

Ответ 5

Перевод чебурека на перевод VB.NET:

Private Function GetMimeType(i As Drawing.Image) As String
    Dim imgguid As Guid = i.RawFormat.Guid
    For Each codec As ImageCodecInfo In ImageCodecInfo.GetImageDecoders()
        If (codec.FormatID = imgguid) Then
            Return codec.MimeType
        End If
    Next
    Return "image/unknown"
End Function

Ответ 6

Я попробовал метод Cheburek для сравнения guid. но для некоторых изображений png изображения не совпадали. поэтому мне пришлось написать логику, которая будет использовать как методы, упомянутые решением Маттиаса Уттке, так и решение Чебурека.

Сначала я проверял с помощью ImageCodecinfo, и если код не нашел образ, тогда я сравнил изображение с помощью решения Matthias Wuttke.

Если оба вышеупомянутых решения не сработали, то используется метод расширения для получения типа файла mime.

если тип mime изменяется, тогда файл также изменяется, мы вычисляем контрольную сумму загруженных файлов, чтобы соответствовать контрольной сумме исходного файла на сервере.. так что для нас было важно получить правильный файл в качестве вывода.

Ответ 7

Ответ Cesare Imperiali выше работал в моих тестах. Единственным недостатком (если это имеет значение) является то, что .ToString() для Jpeg возвращает "[ImageFormat: b96b3cae-0728-11d3-9d7b-0000f81ef32e]" вместо "Jpeg".

Если это важно для вас, вы можете получить точный статический ImageFormat с меньшим количеством кода:

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);

Ответ 8

Свежий, современный и общий ответ для поиска расширения изображения в RawFormat и сохранения выглядит так:

var formatDescription = ImageCodecInfo.GetImageDecoders().FirstOrDefault(w => w.FormatID == image.RawFormat.Guid)?.FormatDescription;

filePath = Path.ChangeExtension(filePath, formatDescription);

image.Save(filePath);