Каков самый быстрый способ загрузки и изменения размера изображения?

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

Вопрос

Мне нужно отобразить миниатюры изображений в заданном каталоге.Я использую TFileStream для чтения файла изображения перед загрузкой изображения в компонент изображения.Затем размер растрового изображения изменяется до размера миниатюры и присваивается компоненту TImage в TScrollBox.

Кажется, это работает нормально, но довольно сильно замедляется при увеличении изображений.

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

Спасибо, Питер

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

Решение

Не совсем. Что вы можете сделать, так это изменить их размер в фоновом потоке и использовать «местозаполнитель» изображение, пока изменение размера не будет сделано. Затем я бы сохранил эти изображения с измененным размером в какой-то файл кэша для последующей обработки (это делает Windows и вызывает кэш thumbs.db в текущем каталоге).

У вас есть несколько вариантов самой архитектуры потоков. Один поток, который делает все изображения, или пул потоков, где поток знает только, как обрабатывать одно изображение. AsyncCalls - это еще один способ, позволяющий упростить задачу.

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

Я дополню ответ скамрадта попыткой сделать это как можно быстрее.Для этого вам следует

  • оптимизация ввода-вывода
  • используйте несколько потоков, чтобы использовать несколько ядер процессора и поддерживать работоспособность даже одного ядра процессора во время чтения (или записи) файлов

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

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

Для достижения наилучших результатов чтение (и запись) файлов также не должно происходить в основном потоке (GUI) вашего приложения.Это позволило бы предположить следующий дизайн:

  • Попросите один поток прочитать файлы в TGraphic objects и поместить их в потокобезопасный список.
  • Попросите пул потоков дождаться списка файлов исходного размера и попросите один поток обработать один TGraphic объект, изменить его размер в другой TGraphic объект и добавить это в другой потокобезопасный список.
  • Уведомляйте поток графического интерфейса о каждом уменьшенном изображении, добавленном в список, чтобы его можно было отобразить.
  • Если эскизы должны быть записаны в файл, сделайте это также в потоке чтения (объяснение см. Выше).

Редактировать:

Перечитывая ваш вопрос, я замечаю, что вам, возможно, нужно изменить размер только одного изображения, и в этом случае, конечно, достаточно одного фонового потока.Я все равно оставлю свой ответ на месте, может быть, когда-нибудь он пригодится кому-нибудь еще.Это то, что я узнал из одного из моих последних проектов, где финальной программе, возможно, требовалось немного больше скорости, но в пиковые моменты она использовала только около 75% четырехъядерного процессора.Отделение ввода-вывода от обработки имело бы значение.

Я часто использую TJPEGImage с Scale: = jsEighth (в Delphi 7). Это действительно быстро, потому что декомпрессия JPEG может пропустить много данных, чтобы заполнить растровое изображение только восьмой ширины и высоты.

Другим вариантом является использование метода оболочки для извлечения эскиза , который довольно быстро а

Я занимаюсь бизнесом, и просто загружаю изображения в графический процессор с помощью OpenGL. (обычно 20x2048x2000x8bpp в секунду), bmp на текстуру и масштабирование видеокарты (win32, заголовки opengl Майка Лишке)

Загрузка такого изображения стоит 5-10 мс в зависимости от конкретной видеокарты (если она не встроена, а серии NVIDIA 7300 или новее. Также могут быть реализованы новейшие интегрированные графические процессоры). Масштабирование и отображение стоит 300US. Это означает, что клиенты могут перемещаться и масштабироваться как сумасшедшие, не касаясь приложения Я рисую наложение (которое раньше было tmetafile, но теперь является собственным форматом) поверх него.

Моя самая большая картинка - 4096x7000x8bpp, которая отображается и масштабируется менее чем за 30 мс. (GF 8600)

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

(некоторые типичные размеры: Серия nv6x00: 2k * 2k, но загрузка практически безубыточна по сравнению с GDI Серия nv7x00: 4k * 4k Для меня базовые карты. GF7300 как $ 20-40 серия nv8x00: 8k * 8k )

Обратите внимание, что это может быть не для всех. Но если вам повезло указать аппаратные ограничения, это может сработать. Основная проблема - это ноутбуки, такие как Thinkpad, графические процессоры которых старше, чем ноутбук avg, которые, в свою очередь, часто отстают от настольных компьютеров.

Я выбрал OpenGL вместо DirectX, потому что он более статичен во времени и его легче найти, не относящееся к игре.

Попробуйте взглянуть на библиотеку Graphics32 : она очень хорошо рисует и работает Отлично с растровыми изображениями. Они Thread - Safe с хорошим примером, и это абсолютно бесплатно.

Используйте возможности Windows для создания миниатюр. Помните, что скрытые файлы Thumbs.db в папках, которые содержат изображения?

Я реализовал что-то вроде этой функции, но в VB. Мое программное обеспечение способно создавать эскизы из 100 файлов (смешанного размера) примерно за 10 секунд.

Я не могу преобразовать его в Delphi.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top