Форум: "Media";
Текущий архив: 2006.01.22;
Скачать: [xml.tar.bz2];
ВнизКак быстро загрузить и отобразить JPEG ? Найти похожие ветки
← →
alexandr-m © (2005-08-09 18:15) [0]Все примеры которые были найдены в сети - медленные. Картинка JPEG с современного фотоаппарата размером 5Мб грузится и отображается минимум 1.5-2 секунды. Хочется сделать этот процесс моментальным.
Скажем фоновая подгрузка следующей картинки для последующего моментального отображения.
← →
Eraser © (2005-08-09 20:28) [1]alexandr-m © (09.08.05 18:15)
Скорее всего быстрее вряд ли получится. Скорость ограничена ресурсами конкретного компьютера. А декодирование jpeg картинки достаточно "процессороёмкий" процесс.
← →
alexandr-m © (2005-08-09 23:22) [2]а нельзя ли этот "процессороёмкий" процесс проводить в фоновом режиме подгружая следующую картинку пока юзер смотрит на ту которая загрузилась?
← →
Eraser © (2005-08-09 23:52) [3]alexandr-m © (09.08.05 23:22) [2]
Можно! А какие проблемы в реализации этого?
← →
programania © (2005-08-10 03:52) [4]Для ускорения загрузки Jpeg можно ещеTJPEGScale = (jsFullSize, jsHalf, jsQuarter, jsEighth);грузить сначала не jsFullSize и показывать все равно большая картинка в экран не влезета потом jsFullSize уже незаметно пока что-то не нажмути вначале делать масштабирование не качественно но быстро, а потом уже улучшено.А для картинок больше 1mb лучше заранее сделать миниатюры.
← →
miek © (2005-08-10 09:09) [5]В принципе, 2 секунды на такой файл это много, ACDSEE распаковывает значительно быстрее. Значит, надо искать в сети более быстрый модуль для декодирования. Или библиотеку. IJL (Intel JPEG Library) здесь первый кандидат.
← →
WondeRu © (2005-08-10 15:30) [6]miek © (10.08.05 9:09) [5]
ACDSEE распаковывает значительно быстрее
ACDSEE - кеширует! так что Ваше предположение - бред!
← →
Ландграф Павел © (2005-08-10 20:16) [7]И куда он их кеширует? имхо такой же бред, что, всю папку в 2 гега jpg`ов можно прокешировать? Специально провел тест и именно 2 гега скопировал всех моих картинок из разных папок в одну и все файлы переименовал, открывается ТАКЖЕ БЫСТРО!
← →
Alexander Panov © (2005-08-10 20:38) [8]Ландграф Павел © (10.08.05 20:16) [7]
В ACDSee используется не кэширование, а предзагрузка. Т.е. при последовательном просмотре рисунков программа предварительно загружает следующий по списку файл в отдельный буфер и обрабатывает его. При переходе пользователем на след. рисунок загруженный рисунок уже не загружается, а лишь отображается на экране.
← →
Ландграф Павел © (2005-08-10 21:57) [9]Ну в принципе я так думал, что в отдельном потоке обрабатываются след. картинка по списку, ну и библиотека загрузки думаю тоже не малую роль вносит... на асме будет веселее чем на языках высокого уровня
← →
miek © (2005-08-11 09:50) [10]>ACDSEE - кеширует! так что Ваше предположение - бред!
Одно другому не мешает. Да, кэширует.
Но даже если картинки нет в кэше, он работает быстро. Тут, правда, есть одно "но" - какой номинальный размер у картинки? 800x600 или 3000x3000? И то и другое можно сжать в 5МБ. Для первого случая 1,5 сек много.
← →
Sapersky (2005-08-11 10:42) [11]Загрузка на P3-667 картинки 4096 * 4096, ужатой до 500 кб:
KOLJpegObj (аналог стандартного jpeg.pas): 2700 мс
IJL: 710 мс
Та же картинка с хорошим качеством (2.5 мб):
KOLJpegObj: 3000 мс
IJL: 820 мс
Единственный недостаток IJL - относительно большой размер (DLL в 370 кб, тот же JpegObj - около 70 кб). Хотя и 370 кб по современным меркам немного.
Пример использования:
http://prdownloads.sourceforge.net/skinner/FastLib.zip?download
← →
alexandr-m © (2005-08-11 20:09) [12]>ACDSee используется не кэширование, а предзагрузка. Т.е. при >последовательном просмотре рисунков программа предварительно >загружает следующий по списку файл в отдельный буфер и >обрабатывает его. При переходе пользователем на след. рисунок >загруженный рисунок уже не загружается, а лишь отображается на >экране.
Это я и хочу сделать, но во время загрузки следующей картинки прога висит, так как идёт процесс считывания с винта этих 5 Мб. Отображается потом моментально, а вот как сделать этот процесс загрузки низкоприоритетным чтобы он не вешал всё остальное и можно было жмакать на кнопки и т п.
← →
alexandr-m © (2005-08-11 20:12) [13]>Та же картинка с хорошим качеством (2.5 мб):
>KOLJpegObj: 3000 мс
>IJL: 820 мс
Значит качественную картинку в 5 метров с цифровика с хорошим качеством IJL: 820 мс *2= 1640 мс т.е. 1.5 секунды - это уже тормозззззззззз. Пробовал проги которые пользуют IJL именно такое время у них и уходит на это. Да и ACDCEE не чемпион при больших картинках так же тормозит.
← →
alexandr-m © (2005-08-11 20:21) [14]>http://prdownloads.sourceforge.net/skinner/FastLib.zip?download
загрузка картинки 1.5 метра те же 1.5 сек что и у делфийского TImage
← →
alexandr-m © (2005-08-11 20:21) [15]>http://prdownloads.sourceforge.net/skinner/FastLib.zip?download
загрузка 5-меировой картинки те же 1.5 сек что и у делфийского TImage
← →
Alexander Panov © (2005-08-11 21:25) [16]alexandr-m © (11.08.05 20:09) [12]
Это я и хочу сделать, но во время загрузки следующей картинки прога висит
Загружай в отдельном потоке с пониженным приоритетом.
← →
Sapersky (2005-08-12 11:10) [17]Значит качественную картинку в 5 метров с цифровика с хорошим качеством IJL: 820 мс *2= 1640 мс т.е. 1.5 секунды - это уже тормозззззззззз
820 мс - это результат весьма престарелого по нынешним временам процессора... (P3-667)
загрузка 5-меировой картинки те же 1.5 сек что и у делфийского TImage
Странно. У меня IJL стабильно быстрее (протестировал ещё с 7 мб файлом). Или - как посмотреть - TImage/KOLJpegObj медленнее (думал на версию Дельфи - но в 5 и 7, во всяком случае, всё практически одинаково, 7 даже несколько медленнее).
Процессор не Athlon? Может, Intel Jpeg Library с ним принципиально не хочет быстро работать.
Ещё зависит от типа файла. Прогрессивные JPG, например, грузятся медленнее, и IJL на них даёт меньшее ускорение (но оно есть - в 1.5 раза).
← →
Sapersky (2005-08-12 11:41) [18]Понял в чём дело - IJL быстрее при выключенном Smoothing (для качественной картинки он и не нужен).
В TBumpForm.LoadImage:
LoadJPGFile(Tmp,FileName,False);
← →
Jeer © (2005-08-12 12:27) [19]P-IV 2G
jpg 96% 4M 3000x3000 310 ms
← →
alexandr-m © (2005-08-14 16:07) [20]test
← →
alexandr-m © (2005-08-14 16:27) [21]>В ACDSee используется не кэширование, а предзагрузка. Т.е. при >последовательном просмотре рисунков программа предварительно >загружает следующий по списку файл в отдельный буфер и >обрабатывает его.
>Загружай в отдельном потоке с пониженным приоритетом.
Именно это и хочу сделать. Создал новый поток, но не могу из него вызвать компонент из первой формы, на попытку
Form1.Image2.Picture.LoadFromFile("c:\1YPB290680.JPG");
из нового Unit1.pas в котором создался этот Thread пишет:
Undeclared Indetifier Form1
← →
alexandr-m © (2005-08-14 17:13) [22]С этим разобрался надо было прописать
implementation
uses unit1;
теперь не могу вызвать эту процедуру прописанную в другом юните:
procedure LoadNextImage.execute;
begin
SetName;
{ Place thread code here }
Form1.Image3.Picture.LoadFromFile("c:\1YPB290681.JPG");
end;
пишу в первой форме:
unit1.LoadNextImage(execute);
ошибка: Undeclared Indetifier Form1
← →
alexandr-m © (2005-08-14 17:22) [23]по идее должно вызываться типа
Synchronize(UpdateCaption);
пишу Synchronize(unit1.LoadNextImage(execute));
ошибка missing operator.
как блин вызвать эту процедуру с потоком?
← →
miek © (2005-08-15 10:56) [24]В обоих модулях пропиши uses друг друга.
← →
alexandr-m © (2005-08-15 15:34) [25]уже прописал, я же написал выше.
В обоих модулях пропиши uses друг друга.
← →
Alexander Panov © (2005-08-15 15:47) [26]Ты бы код потока привел лучше.
← →
alexandr-m © (2005-08-15 16:04) [27]http://delphimaster.net/view/8-1124107398/
вот создал отдельный топик по потоку, там привёл весь код.
← →
Alexander Panov © (2005-08-15 18:28) [28]Вот написал примерный код:
{$WARN UNIT_PLATFORM OFF}
{$WARN SYMBOL_PLATFORM OFF}
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, Buttons, ExtCtrls, StdCtrls, ToolWin, JPeg,FIleCtrl;
type
PFileRec=^TFileRec;
TFileRec=record
FilePath: String;
FullFileName: String;
FileName: String;
FileExt: String;
FileSize: Integer;
isDir: Boolean;
end;
TFileRecArray=array of TFileRec;
EErrorJpeg=Exception;
TPreloadStatus=(psNone,psProcess,psComplete);
TPreloadWait=(pwWait);
TCompleteProc=procedure(const FilePath: String) of object;
TPreloadJpeg=class(TThread)
private
FFilePath: String;
FJpeg: TJpegImage;
FComplete: TCompleteProc;
FStatus: TPreloadStatus;
procedure FOnComplete;
function GetJpegImage: TJpegImage;
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
procedure Release;
procedure Load(const FilePath: String); overload;
procedure Load(const FilePath: String;aWait: TPreloadWait); overload;
property OnComplete: TCompleteProc read FCOmplete write FComplete;
property Status: TPreloadStatus read FStatus;
property JpegImage: TJpegImage read GetJpegImage;
end;
TForm1 = class(TForm)
sb: TStatusBar;
ToolBar1: TToolBar;
lb: TListBox;
im: TImage;
SpeedButton1: TSpeedButton;
procedure FormCanResize(Sender: TObject; var NewWidth,
NewHeight: Integer; var Resize: Boolean);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure SpeedButton1Click(Sender: TObject);
procedure lbClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function DirSelect(const RootDir: String): String;
var
Form1: TForm1;
PJ: TPreloadJpeg;
LastIndex: Integer;
implementation
{$R *.dfm}
function GetFileName(const FullFileName: String): String;
var
i: Integer;
begin
Result := FullFileName;
for i := Length(FullFileName) downto 1 do
begin
if FullFileName[i]="." then
begin
Result := Copy(FullFileName,1,i-1);
Break;
end;
end;
end;
function GetFileExt(const FullFileName: String): String;
var
i: Integer;
begin
Result := "";
for i := Length(FullFileName)-1 downto 1 do
begin
if FullFileName[i]="." then
begin
Result := Copy(FullFileName,i+1,Length(FullFileName)-i);
Break;
end;
end;
end;
procedure GetFilesSimple(const aPath: String;var FileArr: TFileRecArray);
var
SR: TSearchRec;
tPath: String;
begin
tPath := IncludeTrailingBackSlash(aPath);
if FindFirst(tPath+"\*.*",faAnyFile,SR)=0 then
begin
try
repeat
if (SR.Name=".") or (SR.Name="..") then Continue;
if (SR.Attr and faDirectory)<>0 then
begin
Continue;
SetLength(FileArr,Length(FileArr)+1);
FileArr[High(FileArr)].FilePath := tPath+SR.Name;
FileArr[High(FileArr)].FullFileName := SR.Name;
FileArr[High(FileArr)].FileName := GetFileName(SR.Name);
FileArr[High(FileArr)].FileName := GetFileExt(SR.Name);
FileArr[High(FileArr)].isDir := True;
GetFilesSimple(tPath+SR.Name,FileArr);
end;
if UpperCase(GetFileExt(SR.Name))="JPG" then
begin
SetLength(FileArr,Length(FileArr)+1);
FileArr[High(FileArr)].FilePath := tPath+SR.Name;
FileArr[High(FileArr)].FullFileName := SR.Name;
FileArr[High(FileArr)].FileName := GetFileName(SR.Name);
FileArr[High(FileArr)].FileExt := GetFileExt(SR.Name);
FileArr[High(FileArr)].FileSize := SR.Size;
FileArr[High(FileArr)].isDir := False;
end;
until FindNext(SR)<>0;
finally
Sysutils.FindClose(SR);
end;
end;
end;
procedure TForm1.FormCanResize(Sender: TObject; var NewWidth,
NewHeight: Integer; var Resize: Boolean);
begin
sb.Panels[0].Width := Form1.ClientWidth-30;
end;
function DirSelect(const RootDir: String): String;
var
Dir: String;
begin
Dir := RootDir;
if SelectDirectory(
Dir,
[sdAllowCreate, sdPerformCreate, sdPrompt],
0)
then Result := Dir
else Result := "";
end;
{ TPreloadJpeg }
constructor TPreloadJpeg.Create;
begin
inherited Create(True);
FreeOnTerminate := True;
FJpeg := TJpegImage.Create;
FStatus := psNone;
Resume;
end;
destructor TPreloadJpeg.Destroy;
begin
FJpeg.Free;
inherited;
end;
procedure TPreloadJpeg.Execute;
begin
while not Terminated do
begin
Suspend;
if Terminated then Break;
try
FJpeg.LoadFromFile(FFilePath);
Synchronize(FOnComplete);
except
fStatus := psNone;
end;
end;
end;
procedure TPreloadJpeg.FOnComplete;
begin
FStatus := psComplete;
if Assigned(FComplete) then FComplete(FFilePath);
end;
function TPreloadJpeg.GetJpegImage: TJpegImage;
begin
if FStatus = psProcess then raise EErrorJpeg.Create("Не закончена загрузка рисунка");
if FStatus = psNone then REsult := nil else Result := FJpeg;
end;
procedure TPreloadJpeg.Load(const FilePath: String);
begin
if FStatus = psProcess then raise EErrorJpeg.Create("Не закончена загрузка предыдущего рисунка");
fStatus := psProcess;
If FilePath=FFilePath then Exit;
FFilePath := FilePath;
Resume;
end;
procedure TPreloadJpeg.Load(const FilePath: String; aWait: TPreloadWait);
begin
Load(FilePath);
while FStatus<>psComplete do Sleep(1);
end;
procedure TPreloadJpeg.Release;
begin
Terminate;
Resume;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
PJ := TPreloadJpeg.Create;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
← →
Alexander Panov © (2005-08-15 18:28) [29]
PJ.Release;
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
s: String;
fr: TFileRecArray;
i: Integer;
begin
s := DirSelect("e:\data\photo");
if s="" then Exit;
GetFilesSimple(s,fr);
lb.Items.Clear;
for i := Low(fr) to High(fr) do
begin
lb.Items.Add(fr[i].FilePath);
end;
lb.ItemIndex := 0;
LastIndex := 0;
if (PJ.FStatus<>psProcess) and (lb.Items.Count>1) then PJ.Load(lb.Items[1]);
end;
procedure TForm1.lbClick(Sender: TObject);
var
Index: Integer;
begin
Index := lb.ItemIndex;
if Index=LastIndex then
begin
if PJ.FStatus=psComplete then im.Picture.Assign(PJ.JpegImage);
Exit;
end;
if PJ.FStatus=psComplete then im.Picture.Assign(PJ.JpegImage);
if PJ.FStatus=psNone then
begin
PJ.Load(lb.Items[Index],pwWait);
im.Picture.Assign(PJ.JpegImage);
end;
if Index>LastIndex then
begin
if Index+1<lb.Items.Count then
begin
LastIndex := Index;
Index := Index+1;
PJ.Load(lb.Items[Index]);
end;
end
else
begin
if Index-1>=0 then
begin
LastIndex := Index;
Index := Index-1;
PJ.Load(lb.Items[Index]);
end;
end;
end;
end.
Как должен работать - смотри по коду, разбирайся.
Я отлаживать до конца не стал, но общая идея, работа с потоком понятна.
Вот ссылка на проект:
ftp://ftp.almar.net.ru/pub/pload/pload.zip
Страницы: 1 вся ветка
Форум: "Media";
Текущий архив: 2006.01.22;
Скачать: [xml.tar.bz2];
Память: 0.58 MB
Время: 0.053 c