Заблудился, что называется в 3 соснах. Долго отлаживал этот простой код и Аллилуйя теперь все работает как нужно. С одной стороны сказалась специфика UniGUI, с другой нюансы Delphi. Я уже писал код для уменьшения картинок в потоке, но там все только для VCL и может быть FireMonkey. В UniGUI же я столкнулся с тем, что не смог воспользоваться методом LoadFromFile для экземпляра класса TWIC, что ввело меня в ступор. Но слава Богу нашелся другой вариант.
В общем вот элегантное решение, на мой взгляд, на примере UniGUI фрэймворка, но оно же подойдет для VCL если TuniImage заменить на TImage
Способ №1 через GDI+
Способ универсальный – уменьшает пропорционально картинку по настоящему, после чего ее можно сохранить на диск. Второй же способ, который будет приведен ниже уменьшает картинку только на уровне uniimage, а если копнуть глубже, Uniimage.picture.width, например, то этот параметр останется неизменным. Поэтому, я остановился на 1 способе.
1 |
uses GDIPOBJ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
procedure TDiminishPic.ProportionalDiminishPicSize2 (FilePath:string; maxWidth,maxHeight:Integer; var bmpDest:TBitmap); var uniimage:TUniImage; currentWidth: Integer; currentHeight: Integer; koeff: Extended; NewWidth: Integer; NewHeight: Integer; begin // uniimage:=TUniImage.Create(UniMainModule.UniApplication); uniimage.Picture.LoadFromFile(FilePath); currentWidth:=uniimage.Picture.Width; currentHeight:=uniimage.Picture.Height; //Calculating koeff if (currentWidth>maxWidth) or (currentHeight>maxHeight) then koeff:=Min(maxWidth/currentWidth,maxHeight/currentHeight) else koeff:=1; if koeff<>1 then begin NewWidth:=trunc(currentWidth*koeff); NewHeight:=Trunc(currentHeight*koeff); LoadAAImageFromFile(FilePath,NewWidth,NewHeight,bmpDest); end else LoadAAImageFromFile(FilePath,currentWidth,currentHeight,bmpDest); end; |
Собственно уменьшение картинки
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
procedure TDiminishPic.LoadAAImageFromFile(FileName: String; W,H: Integer; Pic: TBitmap); var ImageTemp: TGPImage; graphicsGDIPlus: TGPGraphics; begin if FileExists(FileName) then begin Pic.Width:=W; Pic.Height:=H; graphicsGDIPlus:=TGPGraphics.Create (Pic.Canvas.Handle); ImageTemp:=TGPImage.Create(FileName ); // Trouble here graphicsGDIPlus.DrawImage(ImageTemp , 0,0,W,H); ImageTemp.Free; graphicsGDIPlus.Free; end; end; |
Пример использования
1 2 3 4 5 6 7 8 9 10 11 12 |
... bmp:=tbitmap.Create; DiminishPic.ProportionalDiminishPicSize2( 'C:\DELPHI\MyStudyProjects\379_UniShowCase\Win32\Debug\UploadFolder\1{32B0316E-82F5-4CD8-B0DA-20451D7AC7F0}.JPG', 128, 128, bmp ); bmp.SaveToFile('C:\DELPHI\MyStudyProjects\379_UniShowCase\Win32\Debug\UploadFolder\thumbnails\123_thumb.jpg'); ... |
Способ №2 через uniimage.assign
Подойдет, если не нужно сохранять уменьшенную картинку на диск, а скажем просто загрузить её в uniimage на форме.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
procedure TDiminishPic.ProportionalDiminishPicSize( FilePath:string; var uniimageSource:TUniImage; var uniimageDest:TUniImage; maxWidth:Integer; maxHeight:Integer ); var currentWidth: integer; currentHeight: integer; koeff: Extended; begin // Checks... if FilePath='' then exit; if not ( Assigned(uniimageSource) ) or not ( Assigned(uniimageDest) ) then exit; //Proportional diminishing uniimageSource.Picture.LoadFromFile(FilePath); currentWidth:=uniimageSource.Picture.Width; currentHeight:=uniimageSource.Picture.Height; if (currentWidth>maxWidth) or (currentHeight>maxHeight) then koeff:=Min(maxWidth/currentWidth,maxHeight/currentHeight) else koeff:=1; if koeff<>1 then begin uniimageDest.Width:=Trunc(currentWidth*koeff);//MaxWidth; uniimageDest.Height:=Trunc(currentHeight*koeff);// MaxHeight; uniimageDest.Proportional:=true; uniimageDest.Stretch:=true; uniimageDest.Assign(uniimageSource); end else begin uniimageDest.Width:=uniimageSource.Width; uniimageDest.Height:=uniimageSource.Height; uniimageDest.Assign(uniimageSource); end; end; |
Пример использования кода…
здесь uniimage создаем в коде динамически, а uniimage1 просто добавлен на форму
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
procedure TMainForm.bTestClick(Sender: TObject); var Filepath: string; uniimage:tuniimage; begin Filepath:='C:\Users\YellowFriend\Desktop\Pics\yand.png'; //'C:\DELPHI\MyStudyProjects\379_UniShowCase\Win32\Debug\UploadFolder\1{01A2B584-8E75-4043-AF04-0A3B9E9D4842}.JPG'; uniimage:=TUniImage.Create(UniApplication); ProportionalDiminishPicSize(Filepath,uniimage,UniImage1,128,128); end; |