Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ускорение загрузки изображений, Bitmap = new Bitmap(Filename) тормозит 
V
    Опции темы
rubbiroid
Дата 24.3.2008, 02:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 23.8.2006
Где: Германия

Репутация: нет
Всего: 1



Доброго времени суток!

Пишу каталогизатор фоток (C# .Net 2) и столкнулся с такой проблемой. Для испорта информации о фотке использую стандартный Bitmap и оттуда потом уже получаю разрешение и превьюшку.
Код

Bitmap PhotoBitmap = new Bitmap(File.FullName);
this.Height = (UInt16)PhotoBitmap.Height;
this.Width = (UInt16)PhotoBitmap.Width;
.
.
.
this.PhotoThumb = (Bitmap)PhotoBitmap.GetThumbnailImage(_newWidth, _newHeight, null, IntPtr.Zero);


Все работает хорошо... но медленно... Особенно если в цикле нужно обработать пару сотен фотографий.  Согласно профайлеру 99% времени уходит на 
Код

Bitmap PhotoBitmap = new Bitmap(File.FullName);

Как бы ускорить этот процесс?
З.Ы. Как вариант использовать самописный "декодер" Jpeg и подчитывать только размеры и превьюшку. Но как декодировать саму превьюшку? Я пока не нашел ничего более подробного чем "далее идет упакованные данные превьюшки" (перевод вольный).

Это сообщение отредактировал(а) rubbiroid - 24.3.2008, 02:35
PM MAIL   Вверх
Voyager
Дата 24.3.2008, 10:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 532
Регистрация: 8.2.2005

Репутация: 3
Всего: 18



Не знаю как насчет ускорить, но можно вынести обработку в треды, и при открытии окна превьюшки будут открываться поочередно (в смысле визуально), как в Windows и разных программах аля AcdSee (приложение висеть в ожидании окончания цикла не будет).
PM   Вверх
vponomarov
Дата 24.3.2008, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 407
Регистрация: 11.8.2007
Где: Киев

Репутация: 4
Всего: 12



rubbiroid, можно позаимствовать идею создания привьюшек у горячо любимой винды.
т.е. создавать привьюшки только один раз, а при повторном заходе в каталог грузить их откуда-нибудь а не создавать заново.
еще можно попробовать разобраться как загружать привьюшки из файлов thumbs.db которые создает винда
короче вариантов много smile 


--------------------
user posted image
user posted image
PM MAIL ICQ   Вверх
rubbiroid
Дата 24.3.2008, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 23.8.2006
Где: Германия

Репутация: нет
Всего: 1



vponomarov, Ну так оно и делается. Просто изначально ГДИ, как я понял, загружает ВЕСЬ файл в память (про декодирование не знаю, но мне кажется, что и декодирует). Соответственно, на это уходит много времени - ибо фотки по 2-3 метра. Если же подчитывать только заголовок Jpeg и парсить его ручками, то на это уйдет куда меньше времени ибо не 3 метра загружать надо и не 6МП декодировать. Как подчтать ручками размеры я вроде нашел, но вот что сделать с превьюшкой, которая зашита в фотку, я не знаю. Если кто скинет статейку про jpeg, где описана полная структура файла с EXIF и как что оттуда можно достать (типа Пошаговое создание собственного декодера JPEG) - буду безумно благодарен.
Voyager, Вариант тоже был, вот только никогда не писал многопоточек... Да и если сделать 2 потока (ну или по количеству процессоров), то все начнет упираться в скорость винта. Поэтому и хотель бы получить нужные мне данные НЕ загружая весь файл и НЕ докодируя его целиком.

З.Ы. Кто-нить случаем знает, как определить количество процессоров в системе?

Это сообщение отредактировал(а) rubbiroid - 24.3.2008, 13:17
PM MAIL   Вверх
QryStaL
Дата 24.3.2008, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Intellectual feast
**


Профиль
Группа: Участник
Сообщений: 914
Регистрация: 30.11.2005

Репутация: 14
Всего: 32



Код

Environment.ProcessorCount



--------------------
I don't need a reason being who I am...
PM MAIL ICQ   Вверх
vponomarov
Дата 24.3.2008, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 407
Регистрация: 11.8.2007
Где: Киев

Репутация: 4
Всего: 12



Цитата

Voyager, Вариант тоже был, вот только никогда не писал многопоточек... Да и если сделать 2 потока (ну или по количеству процессоров), то все начнет упираться в скорость винта. Поэтому и хотель бы получить нужные мне данные НЕ загружая весь файл и НЕ докодируя его целиком.

сомневаюсь, что из нескольких потоков будет заметно быстрее. хотя попробовать конечно стоит.

Цитата

Ну так оно и делается

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


--------------------
user posted image
user posted image
PM MAIL ICQ   Вверх
rubbiroid
Дата 24.3.2008, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 23.8.2006
Где: Германия

Репутация: нет
Всего: 1



QryStaL, Пасибо!

Сделал тестовое приложение с многопоточностью. Прирост производительности с двумя потоками почти 100%. Но все равно не хочется загружать весь файл.


vponomarov, моя прога хранит превьюшки в себе. Так что я их получаю только 1 раз. И вот этот один раз на больших каталогах может идти несколько минут. К примеру на 200 фотках - 93 секунды (в 1 поток) на Core2Duo E4300. А если проц послабее? Вот поэтому и не хочется грузить весь файл. Да и смысла в этом особо нет, ибо он мне не нужен (ну, только если в нем самом нет превьюшки и ее надо ручками создавать)

Это сообщение отредактировал(а) rubbiroid - 24.3.2008, 15:42
PM MAIL   Вверх
Kefir
Дата 24.3.2008, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


«Hakuna Matata»
***


Профиль
Группа: Комодератор
Сообщений: 1878
Регистрация: 25.1.2003
Где: Tampere, Suomi

Репутация: 2
Всего: 87



ты хочешь создавать превью без открытия изображения?  smile или я в танке? В итоге ведь получается, что как ни крути - всё равно один раз по всем картинкам пробежать надо. Вот тут-то ты и выхватываешь всё что тебе надо из картинок и записываешь... Или где?
PM MAIL WWW Skype   Вверх
rubbiroid
Дата 24.3.2008, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 23.8.2006
Где: Германия

Репутация: нет
Всего: 1



Kefir, В Jpeg'ах кроме основной картинки хранится еще и превьюшка. Так вот мне она и нужна. 
Мне не нужно декодировать все изображение. Только эту маленькую кртинку. А GDI при создании Битмапа из файла декодирует его, что мне абсолютно не надо.

PM MAIL   Вверх
Rififi
Дата 24.3.2008, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 5
Всего: 36



rubbiroid
поскольку gdi+ при загрузке изображения прокачивает его целиком в память, более оптимальным вариантом будет ручное выдирание exif-тэгов из файла. Правда если там preview отсутствует, то его по-любому надо будет самостоятельно делать. Спецификация на exif здесь: http://exif.org/specifications.html
PM MAIL   Вверх
Kefir
Дата 24.3.2008, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


«Hakuna Matata»
***


Профиль
Группа: Комодератор
Сообщений: 1878
Регистрация: 25.1.2003
Где: Tampere, Suomi

Репутация: 2
Всего: 87



Есть с чего начать - http://www.sentex.net/~mwandel/jhead/
Эта программулька по описанию занимается именно тем, что тебе надо. Покопайся в сырцах и перепиши как тебе надо.
PM MAIL WWW Skype   Вверх
rubbiroid
Дата 24.3.2008, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 23.8.2006
Где: Германия

Репутация: нет
Всего: 1



Kefir, Пасибо, посмотрю.
PM MAIL   Вверх
QryStaL
Дата 30.3.2008, 00:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Intellectual feast
**


Профиль
Группа: Участник
Сообщений: 914
Регистрация: 30.11.2005

Репутация: 14
Всего: 32



 smile 

Код

string path = "D:/test.jpg";
Stream fs = File.OpenRead(path);
Image temp = Image.FromStream(fs, false, false);
Image result = temp.GetThumbnailImage(100, 100, null, IntPtr.Zero);


Это сообщение отредактировал(а) QryStaL - 30.3.2008, 00:49


--------------------
I don't need a reason being who I am...
PM MAIL ICQ   Вверх
Kefir
Дата 30.3.2008, 01:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


«Hakuna Matata»
***


Профиль
Группа: Комодератор
Сообщений: 1878
Регистрация: 25.1.2003
Где: Tampere, Suomi

Репутация: 2
Всего: 87



QryStaL, чем, собстевенно сей метод отличается от сабжевого?
PM MAIL WWW Skype   Вверх
QryStaL
Дата 30.3.2008, 02:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Intellectual feast
**


Профиль
Группа: Участник
Сообщений: 914
Регистрация: 30.11.2005

Репутация: 14
Всего: 32



Kefir, Быстродействием.

200 фотографий (3 МП) обрабатываются меньше секунды.
Pentium 4 3GHz (Одноядерный с HT).

Это сообщение отредактировал(а) QryStaL - 30.3.2008, 02:11


--------------------
I don't need a reason being who I am...
PM MAIL ICQ   Вверх
rubbiroid
Дата 30.3.2008, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 23.8.2006
Где: Германия

Репутация: нет
Всего: 1



На маленьких фотках у меня тоже все быстро работает. Только вот у меня фотки 6 МП. И там не все так быстро уже.
Решил проблему написание собствнного EXIF парсера и добавлением многопоточности. Правда ускорение получилось именно на фотках - там где есть EXIF 2.2 с тумбой и нету JFIF. Скорость - около 350-400 фоток в секунду. Если нужно - могу скинуть код.
PM MAIL   Вверх
QryStaL
Дата 30.3.2008, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Intellectual feast
**


Профиль
Группа: Участник
Сообщений: 914
Регистрация: 30.11.2005

Репутация: 14
Всего: 32



rubbiroid, ты мой код хоть пробовал? Я взял 400 фотографий размером 7Мп, запустил на одноядерном процессоре. Результат - 3 секунды (это без многопоточности). А кода - 4 строчки. Или мы не ищем легких путей?


--------------------
I don't need a reason being who I am...
PM MAIL ICQ   Вверх
rubbiroid
Дата 30.3.2008, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 23.8.2006
Где: Германия

Репутация: нет
Всего: 1



Запускал... Результат такой же как и с моим первым кодом...
Только вот мне не 100 на 100 тумба нужна, а с правильным соотношением сторон (но не более 160*120). Кроме этого еще нужно получить размеры фотки и дату, когда она была сделана. А потом все добавить в коллекцию. 
Выложи весь твой код, я добавлю еще свою обработку и сравню быстродействие.

Это сообщение отредактировал(а) rubbiroid - 30.3.2008, 20:01
PM MAIL   Вверх
QryStaL
Дата 30.3.2008, 22:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Intellectual feast
**


Профиль
Группа: Участник
Сообщений: 914
Регистрация: 30.11.2005

Репутация: 14
Всего: 32



Код

Stream fs = File.OpenRead(file);
Image temp = Image.FromStream(fs, false, false);
int imW = temp.Width;
int imH = temp.Height;
int thumbW = 0;
int thumbH = 0;
double mult = 0;
mult = Math.Max((double)imW / 160, (double)imH / 120);
thumbW = (int)(imW / mult);
thumbH = (int)(imH / mult);
PropertyItem pi = temp.GetPropertyItem(0x0132);
string dateTimeCreated = Encoding.ASCII.GetString(pi.Value).TrimEnd(new char[] { '\0' });
Image result = temp.GetThumbnailImage(thumbW, thumbH, null, IntPtr.Zero);



--------------------
I don't need a reason being who I am...
PM MAIL ICQ   Вверх
rubbiroid
Дата 30.3.2008, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 23.8.2006
Где: Германия

Репутация: нет
Всего: 1



В первый раз не заметил, как ты создавал Image. С отключенной проверкой все работате очень быстро. 
Ну... зато теперь я знаю структуру Jpeg'a smile)))

З.Ы. Кто-нить знает, что майкрософт понимает под "ValidateImageData"? Ведь именно из-за этой проверки все так и тормозило.
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.1123 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.