Получение размеров изображения без чтения всего файла

Есть ли дешевый способ получить размеры изображения (jpg, png, ...)? Предпочтительно я хотел бы достичь этого, используя только стандартную библиотеку классов (из-за ограничений хостинга). Я знаю, что читать заголовок изображения и самому разбирать его должно быть относительно легко, но похоже, что что-то подобное уже должно быть там. Кроме того, я убедился, что следующий фрагмент кода читает все изображение (что мне не нужно):

using System;
using System.Drawing;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Image img = new Bitmap("test.png");
            System.Console.WriteLine(img.Width + " x " + img.Height);
        }
    }
}

Было бы полезно, если бы вы были более конкретны в самом вопросе. Теги сказали мне .net и C#, и вам нужна стандартная библиотека, но какие эти ограничения хостинга вы упоминаете?

wnoise 22.09.2008 00:29

Если у вас есть доступ к пространству имен System.Windows.Media.Imaging (в WPF), см. Этот вопрос SO: stackoverflow.com/questions/784734/…

Charlie 06.12.2013 04:18
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
107
2
83 453
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Вы пробовали использовать классы WPF Imaging? System.Windows.Media.Imaging.BitmapDecoder и др.?

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

Спасибо. Вроде разумно, но на моем хостинге .NET 2.

Jan Zich 21.09.2008 20:50

Отличный ответ. Если вы можете получить ссылку на PresentationCore в своем проекте, это правильный путь.

ojrac 11.01.2010 20:18

В моих модульных тестах эти классы работают не лучше, чем GDI ... по-прежнему требуется ~ 32 КБ для чтения размеров JPEG.

Nariman 20.04.2012 17:53

Итак, чтобы получить размеры изображения OP, как использовать BitmapDecoder?

Chuck Savage 22.10.2013 08:47

См. Этот вопрос SO: stackoverflow.com/questions/784734/…

Charlie 06.12.2013 04:18

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

Да, вы можете это сделать, и код зависит от формата файла. Я работаю на поставщика изображений (Atalasoft), и наш продукт предоставляет GetImageInfo () для каждого кодека, который делает минимум для определения размеров и некоторых других простых для получения данных.

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

Если вам комфортно работать с C, то для получения этой информации также можно использовать бесплатный jpeglib. Готов поспорить, что вы можете сделать это с помощью .NET-библиотек, но я не знаю, как это сделать.

можно ли предположить, что использование new AtalaImage(filepath).Width делает что-то подобное?

drzaus 21.01.2014 02:25

или просто Atalasoft.Imaging.Codec.RegisteredDecoders.GetImageInfo ( fullPath ) .Size

drzaus 21.01.2014 02:27

Первый (AtalaImage) считывает все изображение - второй (GetImageInfo) считывает минимальные метаданные для получения элементов информационного объекта изображения.

Lou Franco 22.01.2014 20:16

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

К счастью, в случае с GIF вся необходимая информация находилась в первых 10 байтах:

Type: Bytes 0-2
Version: Bytes 3-5
Height: Bytes 6-7
Width: Bytes 8-9

PNG немного сложнее (ширина и высота по 4 байта):

Width: Bytes 16-19
Height: Bytes 20-23

Как упоминалось выше, wotsit - хороший сайт для подробных спецификаций по форматам изображений и данных, хотя спецификации PNG в pnglib гораздо более детализированы. Однако я думаю, что запись в Википедии о форматах PNG и Гифка - лучшее место для начала.

Вот мой исходный код для проверки GIF, я также придумал кое-что для PNG:

using System;
using System.IO;
using System.Text;

public class ImageSizeTest
{
    public static void Main()
    {
        byte[] bytes = new byte[10];

        string gifFile = @"D:\Personal\Images&Pics\iProduct.gif";
        using (FileStream fs = File.OpenRead(gifFile))
        {
            fs.Read(bytes, 0, 10); // type (3 bytes), version (3 bytes), width (2 bytes), height (2 bytes)
        }
        displayGifInfo(bytes);

        string pngFile = @"D:\Personal\Images&Pics\WaveletsGamma.png";
        using (FileStream fs = File.OpenRead(pngFile))
        {
            fs.Seek(16, SeekOrigin.Begin); // jump to the 16th byte where width and height information is stored
            fs.Read(bytes, 0, 8); // width (4 bytes), height (4 bytes)
        }
        displayPngInfo(bytes);
    }

    public static void displayGifInfo(byte[] bytes)
    {
        string type = Encoding.ASCII.GetString(bytes, 0, 3);
        string version = Encoding.ASCII.GetString(bytes, 3, 3);

        int width = bytes[6] | bytes[7] << 8; // byte 6 and 7 contain the width but in network byte order so byte 7 has to be left-shifted 8 places and bit-masked to byte 6
        int height = bytes[8] | bytes[9] << 8; // same for height

        Console.WriteLine("GIF\nType: {0}\nVersion: {1}\nWidth: {2}\nHeight: {3}\n", type, version, width, height);
    }

    public static void displayPngInfo(byte[] bytes)
    {
        int width = 0, height = 0;

        for (int i = 0; i <= 3; i++)
        {
            width = bytes[i] | width << 8;
            height = bytes[i + 4] | height << 8;            
        }

        Console.WriteLine("PNG\nWidth: {0}\nHeight: {1}\n", width, height);  
    }
}
Ответ принят как подходящий

Лучше всего, как всегда, найти хорошо протестированную библиотеку. Однако вы сказали, что это сложно, поэтому вот какой-то хитроумный, в основном непроверенный код, который должен работать в изрядном количестве случаев:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;

namespace ImageDimensions
{
    public static class ImageHelper
    {
        const string errorMessage = "Could not recognize image format.";

        private static Dictionary<byte[], Func<BinaryReader, Size>> imageFormatDecoders = new Dictionary<byte[], Func<BinaryReader, Size>>()
        {
            { new byte[]{ 0x42, 0x4D }, DecodeBitmap},
            { new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif },
            { new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DecodeGif },
            { new byte[]{ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, DecodePng },
            { new byte[]{ 0xff, 0xd8 }, DecodeJfif },
        };

        /// <summary>
        /// Gets the dimensions of an image.
        /// </summary>
        /// <param name = "path">The path of the image to get the dimensions of.</param>
        /// <returns>The dimensions of the specified image.</returns>
        /// <exception cref = "ArgumentException">The image was of an unrecognized format.</exception>
        public static Size GetDimensions(string path)
        {
            using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)))
            {
                try
                {
                    return GetDimensions(binaryReader);
                }
                catch (ArgumentException e)
                {
                    if (e.Message.StartsWith(errorMessage))
                    {
                        throw new ArgumentException(errorMessage, "path", e);
                    }
                    else
                    {
                        throw e;
                    }
                }
            }
        }

        /// <summary>
        /// Gets the dimensions of an image.
        /// </summary>
        /// <param name = "path">The path of the image to get the dimensions of.</param>
        /// <returns>The dimensions of the specified image.</returns>
        /// <exception cref = "ArgumentException">The image was of an unrecognized format.</exception>    
        public static Size GetDimensions(BinaryReader binaryReader)
        {
            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] = binaryReader.ReadByte();

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

            throw new ArgumentException(errorMessage, "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 short ReadLittleEndianInt16(this BinaryReader binaryReader)
        {
            byte[] bytes = new byte[sizeof(short)];
            for (int i = 0; i < sizeof(short); i += 1)
            {
                bytes[sizeof(short) - 1 - i] = binaryReader.ReadByte();
            }
            return BitConverter.ToInt16(bytes, 0);
        }

        private static int ReadLittleEndianInt32(this BinaryReader binaryReader)
        {
            byte[] bytes = new byte[sizeof(int)];
            for (int i = 0; i < sizeof(int); i += 1)
            {
                bytes[sizeof(int) - 1 - i] = binaryReader.ReadByte();
            }
            return BitConverter.ToInt32(bytes, 0);
        }

        private static Size DecodeBitmap(BinaryReader binaryReader)
        {
            binaryReader.ReadBytes(16);
            int width = binaryReader.ReadInt32();
            int height = binaryReader.ReadInt32();
            return new Size(width, height);
        }

        private static Size DecodeGif (BinaryReader binaryReader)
        {
            int width = binaryReader.ReadInt16();
            int height = binaryReader.ReadInt16();
            return new Size(width, height);
        }

        private static Size DecodePng(BinaryReader binaryReader)
        {
            binaryReader.ReadBytes(8);
            int width = binaryReader.ReadLittleEndianInt32();
            int height = binaryReader.ReadLittleEndianInt32();
            return new Size(width, height);
        }

        private static Size DecodeJfif (BinaryReader binaryReader)
        {
            while (binaryReader.ReadByte() == 0xff)
            {
                byte marker = binaryReader.ReadByte();
                short chunkLength = binaryReader.ReadLittleEndianInt16();

                if (marker == 0xc0)
                {
                    binaryReader.ReadByte();

                    int height = binaryReader.ReadLittleEndianInt16();
                    int width = binaryReader.ReadLittleEndianInt16();
                    return new Size(width, height);
                }

                binaryReader.ReadBytes(chunkLength - 2);
            }

            throw new ArgumentException(errorMessage);
        }
    }
}

Надеюсь, код довольно очевиден. Чтобы добавить новый формат файла, вы добавляете его в imageFormatDecoders с ключом, представляющим собой массив «волшебных битов», которые появляются в начале каждого файла данного формата, а значение - функцией, которая извлекает размер из потока. Большинство форматов достаточно просты, единственная неприятность - это jpeg.

Согласен, JPEG - отстой. Кстати, примечание для людей, которые хотят использовать этот код в будущем: это действительно непроверено. Я прошел через это с помощью тонкой гребенки, и вот что я обнаружил: формат BMP имеет еще один (древний) вариант заголовка, размер которого составляет 16 бит; плюс высота может быть отрицательной (тогда опустите знак). Что касается JPEG - 0xC0 - не единственный заголовок. В основном все от 0xC0 до 0xCF, кроме 0xC4 и 0xCC, являются допустимыми заголовками (вы можете легко получить их в чересстрочных файлах JPG). И, чтобы было веселее, высота может быть равна 0 и указана позже в блоке 0xDC. См. w3.org/Graphics/JPEG/itu-t81.pdf

Vilx- 22.02.2011 15:36

Изменен метод DecodeJfif выше, чтобы расширить исходную (marker == 0xC0) проверку, чтобы она также принимала 0xC1 и 0xC2. Эти другие заголовки начала кадра SOF1 и SOF2 кодируют ширину / высоту в одних и тех же позициях байтов. SOF2 довольно распространен.

Ryan Barton 13.11.2014 23:03

Стандартное предупреждение: вы никогда не должны писать throw e;, а просто throw;. В комментариях вашего XML-документа ко второму GetDimensions также отображается path вместо binaryReader.

Eregrith 22.07.2015 17:18

@RyanBarton Не могли бы вы опубликовать изменения кода? Это действительно очень поможет мне с подобной проблемой. Спасибо.

Steve Johnson 28.12.2016 12:55

@SteveJohnson: отредактированный код для включения проверок SOF1 / SOF2 в DecodeJfif.

Ryan Barton 18.01.2017 19:07

Кроме того, похоже, этот код не принимает файлы JPEG, закодированные в формате EXIF ​​/ TIFF, который выводится многими цифровыми камерами. Он поддерживает только JFIF.

cwills 01.08.2018 05:36

System.Drawing.Image.FromStream (stream, false, false) предоставит вам размеры без загрузки всего изображения, и он работает с любым изображением, которое может загрузить .Net. Непонятно, почему это беспорядочное и неполное решение вызвало так много положительных отзывов.

dynamichael 23.11.2018 23:29

@dynamichael могут возникнуть ситуации, когда у вас нет доступа к этой библиотеке, поэтому эти решения необходимы.

MattyMatt 10.01.2020 10:47

@ MattyMatt2 Из OP: «Лучше всего я хотел бы добиться этого, используя только стандартную библиотеку классов»

dynamichael 12.01.2020 13:20

@dynamichael System.Drawing в наши дни является стандартной библиотекой нет; он основан на GDI +, и существует множество платформ C#, на которых он недоступен.

Nyerguds 23.09.2020 13:43

Кстати, BinaryReader специально предназначен для чтения с прямым порядком байтов. Вспомогательные функции не нужны. Фактически, для части PNG вам нужно читать с прямым порядком байтов; png все внутреннее устройство с прямым порядком байтов.

Nyerguds 23.09.2020 14:42

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

Здесь нет проверки ошибок или какой-либо другой проверки, но в настоящее время она мне нужна для ограниченной задачи, и ее можно легко добавить. Я тестировал его на некотором количестве изображений, и обычно он не читает больше 6K с изображения. Я думаю, это зависит от количества данных EXIF.

using System;
using System.IO;

namespace Test
{

    class Program
    {

        static bool GetJpegDimension(
            string fileName,
            out int width,
            out int height)
        {

            width = height = 0;
            bool found = false;
            bool eof = false;

            FileStream stream = new FileStream(
                fileName,
                FileMode.Open,
                FileAccess.Read);

            BinaryReader reader = new BinaryReader(stream);

            while (!found || eof)
            {

                // read 0xFF and the type
                reader.ReadByte();
                byte type = reader.ReadByte();

                // get length
                int len = 0;
                switch (type)
                {
                    // start and end of the image
                    case 0xD8: 
                    case 0xD9: 
                        len = 0;
                        break;

                    // restart interval
                    case 0xDD: 
                        len = 2;
                        break;

                    // the next two bytes is the length
                    default: 
                        int lenHi = reader.ReadByte();
                        int lenLo = reader.ReadByte();
                        len = (lenHi << 8 | lenLo) - 2;
                        break;
                }

                // EOF?
                if (type == 0xD9)
                    eof = true;

                // process the data
                if (len > 0)
                {

                    // read the data
                    byte[] data = reader.ReadBytes(len);

                    // this is what we are looking for
                    if (type == 0xC0)
                    {
                        width = data[1] << 8 | data[2];
                        height = data[3] << 8 | data[4];
                        found = true;
                    }

                }

            }

            reader.Close();
            stream.Close();

            return found;

        }

        static void Main(string[] args)
        {
            foreach (string file in Directory.GetFiles(args[0]))
            {
                int w, h;
                GetJpegDimension(file, out w, out h);
                System.Console.WriteLine(file + ": " + w + " x " + h);
            }
        }

    }
}

Когда я пытаюсь это сделать, ширина и высота меняются местами.

Jason Sturges 09.03.2017 19:27

@JasonSturges Вам может потребоваться принять во внимание тег Exif Orientation.

Andrew Morton 17.04.2020 13:30

using (FileStream file = new FileStream(this.ImageFileName, FileMode.Open, FileAccess.Read))
{
    using (Image tif = Image.FromStream(stream: file, 
                                        useEmbeddedColorManagement: false,
                                        validateImageData: false))
    {
        float width = tif.PhysicalDimension.Width;
        float height = tif.PhysicalDimension.Height;
        float hresolution = tif.HorizontalResolution;
        float vresolution = tif.VerticalResolution;
     }
}

validateImageData, установленный на false, предотвращает выполнение GDI + дорогостоящего анализа данных изображения, тем самым значительно сокращая время загрузки. Этот вопрос проливает больше света на предмет.

Я использовал ваше решение в качестве последнего ресурса, смешанного с решением ICR, приведенным выше. Были проблемы с JPEG, и решил с этим.

Zorkind 11.09.2013 20:35

Недавно я попробовал это в проекте, где мне нужно было запросить размер более 2000 изображений (в основном jpg и png, очень смешанные размеры), и это действительно было намного быстрее, чем традиционный способ с использованием new Bitmap().

AeonOfTime 24.10.2017 15:39

Лучший ответ. Быстро, чисто и эффективно.

dynamichael 23.11.2018 23:31

Эта функция идеально подходит для окон. но он не работает в Linux, он все равно будет читать весь файл в Linux. (.net ядро ​​2.2)

zhengchun 10.01.2019 10:12

Я сделал это для файла PNG

  var buff = new byte[32];
        using (var d =  File.OpenRead(file))
        {            
            d.Read(buff, 0, 32);
        }
        const int wOff = 16;
        const int hOff = 20;            
        var Widht =BitConverter.ToInt32(new[] {buff[wOff + 3], buff[wOff + 2], buff[wOff + 1], buff[wOff + 0],},0);
        var Height =BitConverter.ToInt32(new[] {buff[hOff + 3], buff[hOff + 2], buff[hOff + 1], buff[hOff + 0],},0);

Обновлен ответ ICR для поддержки прогрессивных jPegs и WebP :)

internal static class ImageHelper
{
    const string errorMessage = "Could not recognise image format.";

    private static Dictionary<byte[], Func<BinaryReader, Size>> imageFormatDecoders = new Dictionary<byte[], Func<BinaryReader, Size>>()
    {
        { new byte[] { 0x42, 0x4D }, DecodeBitmap },
        { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif },
        { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DecodeGif },
        { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, DecodePng },
        { new byte[] { 0xff, 0xd8 }, DecodeJfif },
        { new byte[] { 0x52, 0x49, 0x46, 0x46 }, DecodeWebP },
    };

    /// <summary>        
    /// Gets the dimensions of an image.        
    /// </summary>        
    /// <param name = "path">The path of the image to get the dimensions of.</param>        
    /// <returns>The dimensions of the specified image.</returns>        
    /// <exception cref = "ArgumentException">The image was of an unrecognised format.</exception>            
    public static Size GetDimensions(BinaryReader binaryReader)
    {
        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] = binaryReader.ReadByte();
            foreach(var kvPair in imageFormatDecoders)
            {
                if (StartsWith(magicBytes, kvPair.Key))
                {
                    return kvPair.Value(binaryReader);
                }
            }
        }

        throw new ArgumentException(errorMessage, "binaryReader");
    }

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

        return true;
    }

    private static short ReadLittleEndianInt16(BinaryReader binaryReader)
    {
        byte[] bytes = new byte[sizeof(short)];

        for(int i = 0; i < sizeof(short); i += 1)
        {
            bytes[sizeof(short) - 1 - i] = binaryReader.ReadByte();
        }
        return BitConverter.ToInt16(bytes, 0);
    }

    private static int ReadLittleEndianInt32(BinaryReader binaryReader)
    {
        byte[] bytes = new byte[sizeof(int)];
        for(int i = 0; i < sizeof(int); i += 1)
        {
            bytes[sizeof(int) - 1 - i] = binaryReader.ReadByte();
        }
        return BitConverter.ToInt32(bytes, 0);
    }

    private static Size DecodeBitmap(BinaryReader binaryReader)
    {
        binaryReader.ReadBytes(16);
        int width = binaryReader.ReadInt32();
        int height = binaryReader.ReadInt32();
        return new Size(width, height);
    }

    private static Size DecodeGif (BinaryReader binaryReader)
    {
        int width = binaryReader.ReadInt16();
        int height = binaryReader.ReadInt16();
        return new Size(width, height);
    }

    private static Size DecodePng(BinaryReader binaryReader)
    {
        binaryReader.ReadBytes(8);
        int width = ReadLittleEndianInt32(binaryReader);
        int height = ReadLittleEndianInt32(binaryReader);
        return new Size(width, height);
    }

    private static Size DecodeJfif (BinaryReader binaryReader)
    {
        while(binaryReader.ReadByte() == 0xff)
        {
            byte marker = binaryReader.ReadByte();
            short chunkLength = ReadLittleEndianInt16(binaryReader);
            if (marker == 0xc0 || marker == 0xc2) // c2: progressive
            {
                binaryReader.ReadByte();
                int height = ReadLittleEndianInt16(binaryReader);
                int width = ReadLittleEndianInt16(binaryReader);
                return new Size(width, height);
            }

            if (chunkLength < 0)
            {
                ushort uchunkLength = (ushort)chunkLength;
                binaryReader.ReadBytes(uchunkLength - 2);
            }
            else
            {
                binaryReader.ReadBytes(chunkLength - 2);
            }
        }

        throw new ArgumentException(errorMessage);
    }

    private static Size DecodeWebP(BinaryReader binaryReader)
    {
        binaryReader.ReadUInt32(); // Size
        binaryReader.ReadBytes(15); // WEBP, VP8 + more
        binaryReader.ReadBytes(3); // SYNC

        var width = binaryReader.ReadUInt16() & 0b00_11111111111111; // 14 bits width
        var height = binaryReader.ReadUInt16() & 0b00_11111111111111; // 14 bits height

        return new Size(width, height);
    }

}

Спасибо, что запустили webp. DecodeWebP работает только с изображениями Webp Lossy - developers.google.com/speed/webp/gallery1

Markus 17.09.2020 22:49

Внутреннее устройство png все с прямым порядком байтов (я полагаю, что и gif). А BinaryReader в любом случае всегда читает прямой порядок байтов, независимо от порядка байтов в системе, поэтому существующие вспомогательные функции бесполезны.

Nyerguds 23.09.2020 14:47

Другие вопросы по теме