Получить ширину/высоту изображения без использования Drawing.Image

StackOverflow https://stackoverflow.com/questions/2267534

Вопрос

Я знаю, это звучит странно.У меня есть фотогалерея, которая сохраняет информацию об изображении (url, имя, дату изменения...) с жесткого диска в коллекцию в памяти.

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

есть идеи?, спасибо

Это было полезно?

Решение

Если вы хотите получить эту информацию, не создавая Image экземпляр объекта для каждого изображения, вам нужно будет написать код, который считывает каждый отдельный файл изображения и извлекает информацию.Хотя это, безусловно, возможно, вы обнаружите, что это несколько сложно.Во-первых, вам понадобится код, который считывает первые несколько байтов файла, чтобы определить, какой тип изображения (.bmp, .gif, .png, .jpg и т. д.) содержится в файле, а затем вам понадобится специальный код для извлечения информации для каждого типа изображения, который вы поддерживаете.

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

Если бы я писал эту программу, мой первый фрагмент поступил бы так, как предложил ChrisF, и написал бы что-то вроде:

foreach (string filename in ImageFilenames)
{
    using (Bitmap bmp = new Bitmap(filename))
    {
        // extract and store needed information
    }
}

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

foreach (string filename in ImageFilenames)
{
    using (File f = File.OpenRead(filename))
    {
        // read the first 1K from the file
        // store some placeholder data for height/width
    }
}

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

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

Прошло ДОЛГО времени с тех пор, как я занимался необработанной обработкой файлов изображений, но я думаю, что в наиболее распространенных форматах (GIF, BMP, JPG и т. д.) вы, вероятно, сможете найти высоту/ширину в пределах первых нескольких сотен байт (или меньше) файла.Вам придется выполнить некоторое кодирование для обработки информации заголовка (вероятно, в Интернете есть множество примеров), но это должно значительно ускорить ваш процесс по сравнению с обычным кодированием.считывание всего изображения в память.

Извлекайте информацию из изображений, как это делает Проводник Windows.

Посмотрите здесь:

или здесь:

Или вы также можете прочитать расширенные свойства файла с помощью следующего:

public static void Main(string[] args)
{
    List<string> arrHeaders = new List<string>();    
    Shell32.Shell shell = new Shell32.Shell();
    Shell32.Folder objFolder = shell.NameSpace(@"C:\temp\testprop");

    for( int i = 0; i < short.MaxValue; i++) {
        string header = objFolder.GetDetailsOf(null, i);
        if (String.IsNullOrEmpty(header)) break;
        arrHeaders.Add(header);
    }

    foreach(Shell32.FolderItem2 item in objFolder.Items()) {
        for (int i = 0; i < arrHeaders.Count; i++) {
            Console.WriteLine("{0}\t{1}: {2}", i, 
                arrHeaders[i], objFolder.GetDetailsOf(item, i));
        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top