Получить ширину / высоту изображения без использования Drawing.Image - PullRequest
0 голосов
/ 15 февраля 2010

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

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

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

Ответы [ 3 ]

2 голосов
/ 15 февраля 2010

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

1 голос
/ 15 февраля 2010

Извлечение информации из изображений, как это делает проводник 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));
        }
    }
}
0 голосов
/ 15 февраля 2010

Если вы хотите получить эту информацию без фактического создания экземпляра объекта 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
    }
}

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

...