Обнаружение ContentType Изображения от байта []

Thread.currentThread().getStackTrace() будет обычно содержать метод you’re вызов его от, но существуют ловушки (см. Javadoc):

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

8
задан Nick Clarke 7 August 2009 в 15:53
поделиться

4 ответа

15
ответ дан 5 December 2019 в 04:52
поделиться

Файловые / магические подписи были подходящим вариантом. Ниже представлена ​​рабочая версия кода.

Ссылка: Stackoverflow - Получение размеров изображения без чтения всего файла

ImageFormat contentType = ImageHelper.GetContentType(this.imageBytes);

MemoryStream ms = new MemoryStream(this.imageBytes);
Image image = Image.FromStream(ms);
image.Save(context.HttpContext.Response.OutputStream, contentType);

И затем вспомогательный класс:

public static class ImageHelper
{
    public static ImageFormat GetContentType(byte[] imageBytes)
    {
        MemoryStream ms = new MemoryStream(imageBytes);

        using (BinaryReader br = new BinaryReader(ms))
        {
            int maxMagicBytesLength = imageFormatDecoders.Keys.OrderByDescending(x => x.Length).First().Length;

            byte[] magicBytes = new byte[maxMagicBytesLength];

            for (int i = 0; i < maxMagicBytesLength; i += 1)
            {
                magicBytes[i] = br.ReadByte();

                foreach (var kvPair in imageFormatDecoders)
                {
                    if (magicBytes.StartsWith(kvPair.Key))
                    {
                        return kvPair.Value;
                    }
                }
            }

            throw new ArgumentException("Could not recognise image format", "binaryReader");
        }
    }

    private static bool StartsWith(this byte[] thisBytes, byte[] thatBytes)
    {
        for (int i = 0; i < thatBytes.Length; i += 1)
        {
            if (thisBytes[i] != thatBytes[i])
            {
                return false;
            }
        }
        return true;
    }

    private static Dictionary<byte[], ImageFormat> imageFormatDecoders = new Dictionary<byte[], ImageFormat>()
    {
        { new byte[]{ 0x42, 0x4D }, ImageFormat.Bmp},
        { new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, ImageFormat.Gif },
        { new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, ImageFormat.Gif },
        { new byte[]{ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, ImageFormat.Png },
        { new byte[]{ 0xff, 0xd8 }, ImageFormat.Jpeg },
    };
14
ответ дан 5 December 2019 в 04:52
поделиться

Стандартного способа определения типа контента из встроенного потока не существует. в .NET. Вы можете реализовать свой собственный алгоритм, который мог бы достичь этого для некоторых хорошо известных форматов изображений, прочитав первые несколько байтов и попытавшись сопоставить формат.

1
ответ дан 5 December 2019 в 04:52
поделиться

Подходит ли вам свойство RawFormat ?

MemoryStream ms = new MemoryStream(imageBytes);
Image image = Image.FromStream(ms);
image.Save(context.HttpContext.Response.OutputStream, image.RawFormat);
0
ответ дан 5 December 2019 в 04:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: