Форум: "Media";
Текущий архив: 2006.07.30;
Скачать: [xml.tar.bz2];
ВнизКак быстро уменьшить изображение ? Найти похожие ветки
← →
sco © (2006-02-04 21:11) [0]Я при загрузке проги делая загрузку 24 рисунков достаточно большого размера (~1024-768), точнее их миниатюр(150х150). И ето всё занимает 8 секунд. Когда я закончу прогу у меня будет 120 рисунков, так вот прога будет грузится ~45 секунд! Так конечно не пойдёт. Я знаю что можно поисать способ облегчения например грузить по мере надобности, но думаю что я просто что-то криво очень делаю миниатюры. Всего 24 рисунка и целых 8 сек. Притом что у меня камп быстрый, а там где прога будет юзаться стоят Пентиумы 1-2. Скажите как правильно, БЫСТРО, сделать из большого рисунка - маеленькую копию. Вот мой код, он оптимален, или долго грузится из-за того что код очень кривой?:
function ResizeImage(bitmp: TBitmap; wid, hei: Integer): Boolean;
var
TmpBmp: TBitmap;
ARect: TRect;
begin
Result := False;
try
TmpBmp:=TBitmap.Create;
try
TmpBmp.Width := wid;
TmpBmp.Height := hei;
ARect := Rect(0,0, wid, hei);
TmpBmp.Canvas.StretchDraw(ARect, Bitmp);
bitmp.Assign(TmpBmp);
finally
TmpBmp.Free;
end;
Result := True;
except
Result := False;
end;
end;
procedure MadeMiniImageList;
var
i: longInt;
BitMap,ItogBitMap: TBitMap;
ci: TImage;
begin
BitMap:=TBitMap.Create;
ItogBitMap:=TBitMap.Create;
ItogBitMap.Width:=SizeMiniWidth;
ItogBitMap.Height:=SizeMiniHeight;
with MainF do
begin
MiniImageList.Clear;
if Length(Data)>0 then
for i:=1 to Length(Data) do
begin
//=================== показ загрузки ======
ZastF.LoadI.Width:=(((i*100) div Length(Data))*ZastF.HideI.width) div 100;
ZastF.LoadI.Refresh;
//=================== создание миниатюры ======
if FileExists(DataDir+Data[i-1].FileName) then
begin
BitMap:=LoadJPEG(DataDir+Data[i-1].FileName);
if Max(BitMap.Width,BitMap.Height)=BitMap.Width
then ResizeImage(BitMap,SizeMiniWidth,Round(BitMap.Height*SizeMiniWidth/BitMap.Width))
else ResizeImage(BitMap,Round(SizeMiniHeight*BitMap.Width/BitMap.Height),SizeMiniHeight);
BitMap.Dormant;
ItogBitMap.Canvas.Rectangle(0,0,ItogBitMap.Width,ItogBitMap.Height);
ItogBitmap.Canvas.Draw(
Round((SizeMiniWidth-BitMap.Width)/2),
Round((SizeMiniHeight-BitMap.Height)/2),BitMap);
MiniImageList.Add(ItogBitMap,nil);
end;
end;
end;
BitMap.Free;
ItogBitMap.Free;
end;
← →
PAVIA © (2006-02-05 01:37) [1]Создаешь ты правельно. Только можно сразу рисовать по середине.
Можешь конечно воспользоваться сторонними компонентами для работы с графикой. Может стоит зарание создать миниатюры. Или создовать по ходу.
← →
PAVIA © (2006-02-05 01:57) [2]А зачем BitMap.Dormant; стоит выкинуть будет быстрее.
← →
sco © (2006-02-05 15:12) [3]BitMap.Dormant; ставлю вот зачем
Когда битмап загрузит рисунок она его адаптирует под всякие там proportional-ы и strechi-ы. Но сам битмап остаётся тот же. После dormand-а битмап мтановится таким каким мы его видим. Понял експерементально.
Значит другого пути нет? ASDSee их конкретно быстро делает! Может есть таки алгоритм?
← →
Sco © (2006-02-05 15:15) [4]PAVIA: "Только можно сразу рисовать по середине."
Обьясни, плиз, а то я не понял.
← →
Sapersky (2006-02-05 16:51) [5]BitMap:=LoadJPEG(DataDir+Data[i-1].FileName);
Если рисунки - jpeg, то, возможно, их загрузка тормозит больше создания миниатюр. Можно грузить jpeg в уже уменьшенном в 2, 4, 8 раз виде. Или использовать IJL (Intel Jpeg Library), которая быстрее для большинства jpeg в 2-3 раза.
Ну и, как уже было предложено, грузить "на ходу", т.е. либо в отдельном потоке, либо после загрузки каждого рисовать его и делать ProcessMessages.
ASDSee их конкретно быстро делает!
ASDSee, кроме того что использует приведённые выше методы, сохраняет один раз сделанные миниатюры в своём кэше и потом грузит оттуда. Собственно, этим "грешит" и встроенная гляделка WinXP - скрытый файлик thumbs.db в папках с картинками замечал?
← →
antonn © (2006-02-05 17:50) [6]внесу свое имхо:
вынести TmpBmp: TBitmap; из процедуры ResizeImage(), сздавать его один раз, когда нужно построить все миниатюры, а не при каждой. а еще лучше типа этого (без содержимого ResizeImage()):
BitMap:=LoadJPEG(DataDir+Data[i-1].FileName); //в общем - грузим...
BitMap.canvas.copyrect(rect(0,0,100,100),BitMap.canvas,rect(0,0,BitMap.width,BitMap.height));
BitMap.width:=100;
BitMap.height:=100;
MiniImageList.Add(BitMap);
ItogBitmap.Canvas.Draw() - фуфел, используйте canvas.copyrect() в крайнем случае
← →
sco © (2006-02-06 10:48) [7]to: antonn: Твой способ не срабатывает! Там изображения выходят некоторые правильно некоторые нет. Но я нашёл выход: jpg гружу с scale в восемь раз меньше чем картинка! Очень быстро. Но есть одна проблема вот мой код:
procedure MadeMiniImageList;
var
i: longInt;
t: byte;
BitMap,ItogBitMap: TBitMap;
ci: TImage;
begin
BitMap:=TBitMap.Create;
ItogBitMap:=TBitMap.Create;
ItogBitMap.Width:=SizeMiniWidth;
ItogBitMap.Height:=SizeMiniHeight;
with MainF do
begin
MiniImageList.Clear;
if Length(Data)>0 then
// for t:=1 to 3 do
for i:=1 to Length(Data) do
begin
//=================== показ загрузки ======
ZastF.LoadI.Width:=(((i*100) div Length(Data))*ZastF.HideI.width) div 100;
ZastF.LoadI.Refresh;
//=================== создание миниатюры ======
if FileExists(DataDir+Data[i-1].FileName) then
begin
BitMap:=LoadMiniJPEG(DataDir+Data[i-1].FileName);
if Max(BitMap.Width,BitMap.Height)=BitMap.Width
then ResizeImage(BitMap,SizeMiniWidth,Round(BitMap.Height*SizeMiniWidth/BitMap.Width))
else ResizeImage(BitMap,Round(SizeMiniHeight*BitMap.Width/BitMap.Height),SizeMiniHeight);
ItogBitMap.Canvas.Rectangle(0,0,ItogBitMap.Width,ItogBitMap.Height);
// canvas.copyrect()
ItogBitmap.Canvas.Draw(
Round((SizeMiniWidth-BitMap.Width)/2),
Round((SizeMiniHeight-BitMap.Height)/2),BitMap);
MiniImageList.Add(ItogBitMap,nil);
end;
end;
end;
BitMap.Free;
ItogBitMap.Free;
end;
Дело в том что некоторые картинки не делаются! Просто белый квадрат. И причём когда какие! Почти наугад. Подряд запущу одни и теже, поработаю 10 минут другие! В общем моразм. Нашёл один выход:
if Max(BitMap.Width,BitMap.Height)=BitMap.Width
then ResizeImage(BitMap,SizeMiniWidth,Round(BitMap.Height*SizeMiniWidth/BitMap.Width))
else ResizeImage(BitMap,Round(SizeMiniHeight*BitMap.Width/BitMap.Height),SizeMiniHeight);
BitMap.SaveToFile("temp\"+IntToStr(i)+".bmp"); // вот ета ненужнаяя строчка решает проблему.
Но ета строчка мне не нужна 1, 2 ето нафиг мне каждый раз сохранять файлы! 3 прога будет грузиться с сидюка. 4 полный моразм если я изменю ету строчку на ету: BitMap.SaveToFile(IntToStr(i)+".bmp"); то опять некоторые рисунки белые! идиотизм какойто! Помогите плиз! Проясните ситуацию!
← →
sco © (2006-02-06 10:48) [8]to: antonn: Твой способ не срабатывает! Там изображения выходят некоторые правильно некоторые нет. Но я нашёл выход: jpg гружу с scale в восемь раз меньше чем картинка! Очень быстро. Но есть одна проблема вот мой код:
procedure MadeMiniImageList;
var
i: longInt;
t: byte;
BitMap,ItogBitMap: TBitMap;
ci: TImage;
begin
BitMap:=TBitMap.Create;
ItogBitMap:=TBitMap.Create;
ItogBitMap.Width:=SizeMiniWidth;
ItogBitMap.Height:=SizeMiniHeight;
with MainF do
begin
MiniImageList.Clear;
if Length(Data)>0 then
// for t:=1 to 3 do
for i:=1 to Length(Data) do
begin
//=================== показ загрузки ======
ZastF.LoadI.Width:=(((i*100) div Length(Data))*ZastF.HideI.width) div 100;
ZastF.LoadI.Refresh;
//=================== создание миниатюры ======
if FileExists(DataDir+Data[i-1].FileName) then
begin
BitMap:=LoadMiniJPEG(DataDir+Data[i-1].FileName);
if Max(BitMap.Width,BitMap.Height)=BitMap.Width
then ResizeImage(BitMap,SizeMiniWidth,Round(BitMap.Height*SizeMiniWidth/BitMap.Width))
else ResizeImage(BitMap,Round(SizeMiniHeight*BitMap.Width/BitMap.Height),SizeMiniHeight);
ItogBitMap.Canvas.Rectangle(0,0,ItogBitMap.Width,ItogBitMap.Height);
// canvas.copyrect()
ItogBitmap.Canvas.Draw(
Round((SizeMiniWidth-BitMap.Width)/2),
Round((SizeMiniHeight-BitMap.Height)/2),BitMap);
MiniImageList.Add(ItogBitMap,nil);
end;
end;
end;
BitMap.Free;
ItogBitMap.Free;
end;
Дело в том что некоторые картинки не делаются! Просто белый квадрат. И причём когда какие! Почти наугад. Подряд запущу одни и теже, поработаю 10 минут другие! В общем моразм. Нашёл один выход:
if Max(BitMap.Width,BitMap.Height)=BitMap.Width
then ResizeImage(BitMap,SizeMiniWidth,Round(BitMap.Height*SizeMiniWidth/BitMap.Width))
else ResizeImage(BitMap,Round(SizeMiniHeight*BitMap.Width/BitMap.Height),SizeMiniHeight);
BitMap.SaveToFile("temp\"+IntToStr(i)+".bmp"); // вот ета ненужнаяя строчка решает проблему.
Но ета строчка мне не нужна 1, 2 ето нафиг мне каждый раз сохранять файлы! 3 прога будет грузиться с сидюка. 4 полный моразм если я изменю ету строчку на ету: BitMap.SaveToFile(IntToStr(i)+".bmp"); то опять некоторые рисунки белые! идиотизм какойто! Помогите плиз! Проясните ситуацию!
← →
antonn © (2006-02-06 13:58) [9]sco © (06.02.06 10:48) [7]
to: antonn: Твой способ не срабатывает! Там изображения выходят некоторые правильно некоторые нет.
ну конкретней нужно говрорить, что там не правильно.
на картинке обводка добавляется? это врожденное :)
← →
PAVIA © (2006-02-06 15:46) [10]Дело тут не в уменьшении изоброжении, а в том что картинка грузится долго. Для ускорения загрузки можно использовать такой способ скорость возрастет в 16 раз.
uses jpeg;
var
jpg:TJPEGImage;
begin
jpg:=TJPEGImage.Create;
jpg.Scale:=jsEighth;
//jpg.Scale:=jsQuarter;
jpg.Performance:=jpBestSpeed;
jpg.LoadFromFile("f:\warlok.jpg");
bp:=TBitmap.Create;
bp.Assign(jpg);
← →
sco © (2006-02-06 16:23) [11]to PAVIA: я ето уже сделал, скорость возросла в 8 раз, в общем круто, но одна трабла: некоторые не делаются, и всегда поразному. А больше 8 раз уменьшение мне не нужно, 8 раз и так меньше многих моих рисунков. В общем лажа! И чо делатьь я не знаю.
to antonn: трабла в том что они (минирисунки) иногда меньше чем размер уже адаптированного рисунка, и короче там по бокам пустота, они не центрированиы, в общем видимо етот способ только для больших чем мини рисунков.
← →
Fenik © (2006-02-06 17:02) [12]> antonn © (05.02.06 17:50) [6]
> ItogBitmap.Canvas.Draw() - фуфел, используйте canvas.copyrect()
> в крайнем случае
CopyRect - фуфел, надо юзать BitBlt.
← →
antonn © (2006-02-06 17:31) [13]sco © (06.02.06 16:23) [11]
to antonn: трабла в том что они (минирисунки) иногда меньше чем размер уже адаптированного рисунка
дык они должны растянуться, copyrect() и растянет. а вообще проверять надо размер сначала:) я лишь примерно показал.
Fenik © (06.02.06 17:02) [12]
CopyRect - фуфел, надо юзать BitBlt.
может тогда уж до StretchBlt сразу дойти?
← →
PAVIA © (2006-02-06 18:26) [14]Сделай проверку на размер, а затем jpg.Scale чтобы картинка была больше миниатюры. Затем подгоняешь под свой размер.
> Fenik © (06.02.06 17:02) [12]
> CopyRect - фуфел, надо юзать BitBlt.
> может тогда уж до StretchBlt сразу дойти?
Тогда уж DrawDibDraw.
← →
sco © (2006-02-06 19:33) [15]Не, здесь я уже про большие! Типа слайд-шоу, хотя не типа, а именно так. Но я нажимаю некст, а он ещё секунду думает. Ну ето плохо! Вот и хочу ускорить.
← →
Sco © (2006-02-06 19:35) [16]Я топики перепутал:
"Не, здесь я уже про большие! Типа слайд-шоу, хотя не типа, а именно так. Но я нажимаю некст, а он ещё секунду думает. Ну ето плохо! Вот и хочу ускорить." Ето не сюда, извините за флуд, виноват, в етом топике про маленькие. Ещё раз извиняюсь, админа попрошу его снести.
← →
PAVIA © (2006-02-06 22:47) [17]Если про большии заведи буфер BMP:TBitmap. И грузи в него следующую картинку до таго как будет нажата кнопка Next. А по щелчку по кнопки выводи этот BMP в image
← →
Sapersky (2006-02-07 11:54) [18]Тогда уж DrawDibDraw.
Сам не проверял, но из комментариев к SpriteUtils:
"According to MSDN this procedures should provide faster bitmap drawing than BitBlt, but they doesn"t."
← →
Sco © (2006-02-07 12:57) [19]Всё сделал! Работает, скорость неплохая 120 минирисунков из больших за 3.5 секунды! Вполне подойдёт, а если учесть что гружу по ходу дела отлично.
Страницы: 1 вся ветка
Форум: "Media";
Текущий архив: 2006.07.30;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.011 c