2014-11-25 11 views
8

utworzyć i zainicjować TImageList ...Jak narysować skalowaną wersję obrazów z systemu ImageList?

ImageList:=TImageList.Create(self); 
ImageList.ShareImages:=true; 

mam system ImageList uchwyt dla małych ikon (16x16) ...

ImageList.Handle:=SHGetFileInfo('',0,FileInfo,SizeOf(FileInfo),SHGFI_SYSICONINDEX or SHGFI_SMALLICON); 

A teraz chcę zwrócić ikon na mój płótno kontrolne skalowane do 50x50 pikseli. Jak to robię?

+1

Czy nie może być 2 piksele mniejsze? 48 x 48 pikseli? – TLama

+0

Nie, powiedziałem na przykład 50, ale chcę, aby możliwe było skalowanie do dowolnej wielkości. –

+4

Lepiej uzyskaj rozmiar 48 x 48 lub większy i skaluj go, zamiast rozciągać od 16x16 do 50x50. w każdym przypadku używasz 'ImageList.GetBitmap' i robisz to, co chcesz. lub jeszcze lepiej uzyskać od niego uchwyt Icon i użyć ['DrawIconEx'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms648065 (v = vs.85) .aspx) – kobik

Odpowiedz

9

Upscaling małych ikon nigdy nie jest dobrym pomysłem. Ikona 16X16 jest za mała, aby używać jej w jakikolwiek inny sposób, tak jak jest.

Na początek można dostać większe obrazy powłoki stosując

ImageList.Handle:=SHGetFileInfo('',0,FileInfo,SizeOf(FileInfo),SHGFI_SYSICONINDEX or SHGFI_ICON); 

tych obrazów będzie generalnie 32x32 pix, ale być na bezpiecznej stronie (jeśli system Windows jest uruchomiony w trybie wysokiej dpi) można uzyskać odpowiedni rozmiar od System

uses 
    Winapi.Windows; 

var 
    IconWidth, IconHeight: integer; 

    IconWidth := GetSystemMetrics(SM_CXICON); 
    IconHeight := GetSystemMetrics(SM_CYICON); 

można również uzyskać nawet większe obrazy powłoki z SHGetImageListhttp://msdn.microsoft.com/en-us/library/windows/desktop/bb762185%28v=vs.85%29.aspx

Aby przywrócić ikonę fro m ty ImageList (jeśli ImageList zawiera ikony, aw twoim przypadku to robi) można użyć:

ImageList.GetIcon(Index: Integer; Image: TIcon); 

do skalowania ikon, przy jednoczesnym zachowaniu przejrzystości, do niestandardowych wymiarów można użyć następującego kodu:

procedure StretchDrawIcon(Canvas: TCanvas; Dest: TRect; Icon: TIcon); 
begin 
    DrawIconEx(Canvas.Handle, Dest.Left, Dest.Top, Icon.Handle, Dest.Right - Dest.Left, Dest.Bottom - Dest.Top, 0, 0, DI_NORMAL); 
end; 
3

TImageList nie obsługuje rysowania skalowanego obrazu, rysuje obraz tak jak jest. Jedyną dostępną opcją jest podanie współrzędnych X/Y, w których obraz powinien być narysowany na płótnie docelowym.

Aby przeskalować obraz, należy najpierw wyodrębnić żądany obraz do tymczasowego obiektu TBitmap i wywołać jego metodę Draw(), która umożliwia określenie żądanego prostokąta w docelowym obszarze roboczym. Mapa bitowa będzie następnie rozciągać/skalować swój rysunek, aby wypełnić ten prostokąt w razie potrzeby.

7

Ponieważ ekstrakcji Ikona nie może być rozciągnięta z StretchDraw i wydobytego Bitmap straci przezroczystość jeden sposób może być wyodrębnić ikony i manipulować docelowy płótno za pomocą SetWorldTransform:

uses Shellapi, Math; 

Procedure SetCanvasZoomAndRotation(ACanvas:TCanvas;Zoom:Double;Angle:Double;CenterpointX,CenterpointY:Double); 
var 
    form : tagXFORM; 
    Winkel:Double; 

begin 
     Winkel := DegToRad(Angle); 
     SetGraphicsMode(ACanvas.Handle, GM_ADVANCED); 
     SetMapMode(ACanvas.Handle,MM_ANISOTROPIC); 
     form.eM11 := Zoom * cos(Winkel); 
     form.eM12 := Zoom *Sin(Winkel) ; 
     form.eM21 := Zoom * (-sin(Winkel)); 
     form.eM22 := Zoom * cos(Winkel) ; 
     form.eDx := CenterpointX; 
     form.eDy := CenterpointY; 
     SetWorldTransform(ACanvas.Handle,form); 
end; 

Procedure ResetCanvas(ACanvas:TCanvas); 
begin 
    SetCanvasZoomAndRotation(ACanvas , 1, 0, 0,0); 
end; 

procedure TDemoForm.Button1Click(Sender: TObject); 
var 
FileInfo:_SHFileINfoW; 
ico:TIcon; 
ImageList:TImageList; 
i,x,y:Integer; 
zoom:double; 
begin 
    ImageList:=TImageList.Create(self); 
    ImageList.ShareImages:=true; 
    ImageList.Handle:=SHGetFileInfo('',0,FileInfo,SizeOf(FileInfo),SHGFI_SYSICONINDEX or SHGFI_SMALLICON); 
    ico:=TIcon.Create; 
    try 
    x := 0; 
    y := 0; 
    zoom := 50/Imagelist.Width; 
    SetCanvasZoomAndRotation(Canvas,zoom,0,0 ,0); 
    for I := 0 to ImageList.Count-1 do 
    begin 
    ImageList.GetIcon(i,ico); 
    Canvas.Draw(x,y,ico); 
    inc(x,Imagelist.Width); 
    if (x + Imagelist.Width) * zoom > width then 
     begin 
     x := 0; 
     inc(y,Imagelist.Height); 
     end; 
    end; 
    finally 
    ico.Free; 
    ResetCanvas(Canvas); 
    ImageList.Free; 
    end; 
end; 

Przykładem stosując 250 jako żądany rozmiar: enter image description here

Powiązane problemy