Поиск ширины / высоты изображения PNG с помощью метаданных файла. NET Core 3.1 C# - PullRequest
0 голосов
/ 26 марта 2020

Я использую. NET Core 3.1 с C#, и я использую SDL2 (включая SDL2_image).

Мне нужно найти способ извлечь ширину и высоту файла изображения перед загружая его, используя SDL2_image.IMG_Load(Filename), так как это приводит к сбою, если размеры изображения превышают максимальный размер текстуры графического процессора.

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

Есть ли какой-нибудь свет? весовые, кросс-платформенные решения (которые не требуют большой библиотеки со многими другими предполагаемыми применениями) для определения ширины / высоты файла изображения?

1 Ответ

1 голос
/ 26 марта 2020

Благодаря Джими и Ушедшим в отставку ниндзя я смог выяснить, как получить ширину / высоту из файла PNG.

На самом деле все очень просто. PNG-файлы имеют очень четко определенную структуру, на что указывает здесь Отставной ниндзя).

Я ищу ширину и высоту изображения, которые появляются в виде «кусочка» после 8- длинный байт заголовка. Так как я точно знаю, что мой формат изображения будет PNG и что файл действителен, я могу пропустить все проверки и проверки и перейти непосредственно к самим данным: ширина в байтах 16 - 20 и высота в 20 - 24 (байты 8 - 12 - это имя чанка, IHDR - особый тип чанка, а 12 - 16 - длина чанка; 0, вероятно, потому что это особый чанк фиксированного размера). Я бы порекомендовал проверить страницу википедии, на которую ссылались выше, чтобы понять, как работает формат, это действительно очень просто. Я также открыл один из своих файлов PNG в шестнадцатеричном редакторе, чтобы сравнить реальный пример с форматом PNG, как описано в википедии, чтобы облегчить его понимание.

Таким образом, я смог заставить его работать должным образом с этим кодом:

    public Size GetImageSize(string Filename)
    {
        BinaryReader br = new BinaryReader(File.OpenRead(Filename));
        br.BaseStream.Position = 16;
        byte[] widthbytes = new byte[sizeof(int)];
        for (int i = 0; i < sizeof(int); i++) widthbytes[sizeof(int) - 1 - i ] = br.ReadByte();
        int width = BitConverter.ToInt32(widthbytes, 0);
        byte[] heightbytes = new byte[sizeof(int)];
        for (int i = 0; i < sizeof(int); i++) heightbytes[sizeof(int) - 1 - i] = br.ReadByte();
        int height = BitConverter.ToInt32(heightbytes, 0);
        return new Size(width, height);
    }
...