Подтвердить что ты не робот

Как я могу получить размеры изображения в .NET без загрузки изображения?

Я знаю, как получить размер (x, y) изображения

Image.FromFile("cat.jpg").Size

НО это требует загрузки изображения из памяти.

Когда я просматриваю изображения в Проводнике Windows, он показывает мне размер.

  • Как мне получить доступ к этому размеру?
  • Является ли он надежным для всех изображений? Проводник Windows должен сначала "увидеть" изображение, чтобы размер был доступен. Я не хочу загружать на сервер и не иметь метаданных, прежде чем загружать их в Internet Explorer.

Изменить: Я изменил тему с "размер" на "размеры", чтобы уточнить, какой размер я хотел.

4b9b3361

Ответ 1

Вы можете просто использовать Image.FromStream(Stream, bool, bool) с "ложным" вторым и третьим параметрами, чтобы избежать загрузки файла в память.

Ответ 2

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

Вот вам метод из коробки:)

public static Size GetJpegImageSize(string filename) {
    FileStream stream=null;
    BinaryReader rdr=null;
    try {
        stream=File.OpenRead(filename);
        rdr=new BinaryReader(stream);
        // keep reading packets until we find one that contains Size info
        for(; ; ) {
            byte code=rdr.ReadByte();
            if(code!=0xFF) throw new ApplicationException(
                    "Unexpected value in file "+filename);
            code=rdr.ReadByte();
            switch(code) {
                // filler byte
                case 0xFF:
                    stream.Position--;
                    break;
                // packets without data
                case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: 
                case 0xD5: case 0xD6: case 0xD7: case 0xD8: case 0xD9:
                    break;
                // packets with size information
                case 0xC0: case 0xC1: case 0xC2: case 0xC3:
                case 0xC4: case 0xC5: case 0xC6: case 0xC7:
                case 0xC8: case 0xC9: case 0xCA: case 0xCB:
                case 0xCC: case 0xCD: case 0xCE: case 0xCF:
                    ReadBEUshort(rdr);
                    rdr.ReadByte();
                    ushort h=ReadBEUshort(rdr);
                    ushort w=ReadBEUshort(rdr);
                    return new Size(w, h);
                // irrelevant variable-length packets
                default:
                    int len=ReadBEUshort(rdr);
                    stream.Position+=len-2;
                    break;
            }
        }
    } finally {
        if(rdr!=null) rdr.Close();
        if(stream!=null) stream.Close();
    }
}

private static ushort ReadBEUshort(BinaryReader rdr) {
    ushort hi=rdr.ReadByte();
    hi<<=8;
    ushort lo=rdr.ReadByte();
    return (ushort)(hi|lo);
}

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

Ответ 3

Статья Чтение заголовков изображений для получения ширины и высоты предоставляет несколько возможностей для решения:

  • Многопоточность
  • Чтение заголовков файлов, возврат к загрузке полного изображения, если отсутствует заголовок
  • Создание собственного индекса для атрибутов изображения

Ответ 4

Выполнение этого обычно предполагает фактическое открытие файла и чтение только его заголовка (первые несколько байтов), чтобы найти его формат и размер. Вам не нужно читать весь файл, чтобы узнать его размер. Иногда размер даже в определенном смещении в файле, поэтому поиск размера составляет только 8 байтов.

Вы можете использовать filemon.exe, чтобы узнать, что делает сам проводник Windows, чтобы найти размер.

Ответ 5

В верхней части моей головы - LoadImage() имеет переопределение, указывающее обратный вызов прогресса. Может быть, вы можете использовать это для отмены загрузки после того, как заголовок был прочитан?