Entwickler-Ecke

Dateizugriff - Icon von Programm extrahieren - Schlechte Qualität


LittleBen - So 02.12.12 18:17
Titel: Icon von Programm extrahieren - Schlechte Qualität
Guten Abend,
ich versuche die ganze Zeit ein Icon von einem Programm temporär zu speichern.
Dazu habe ich zwei Funktionen im Netz gefunden, bei denen aber die Qualität der extrahierten Icons überhaupt nicht mit dem original verlgeichbar ist. Extrem zu sehen ist das beim Gimp-Icon.
Hier mal mein Code:

Delphi-Quelltext
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:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
uses ShellApi;

// --------------------- Funktion Nr. 1 -------------------------//

function TotalNumberOfIcons(const FileName: String): Integer;
begin
 if not FileExists(FileName) then Result:= -1
 else Result := ExtractIcon(HInstance, PChar(FileName), $FFFFFFFF);
end;

function GetIconFromFile(const FileName: String; Index: Word;
  Icon: TIcon): Boolean;
begin
 Result:= False;
 showmessage(inttostr(TotalNumberOfIcons(FileName)));
 if (TotalNumberOfIcons(FileName) < 1or ((Index + 1 ) > TotalNumberOfIcons(FileName)) then exit;
 Icon.Handle:= ExtractIcon(HInstance, PChar(FileName), Index);
 Result:= true;
end;

// ---------------------------------------------------------------//

// --------------------- Funktion Nr. 2 -------------------------//

function ExtractIcons(exeFilename,icoOutFileName:String;icoSize:Integer): boolean;
const
{$ifdef UNICODE}
 ExtractProcName='PrivateExtractIconsW';
{$else}
 ExtractProcName='PrivateExtractIconsA';
{$endif}
type
  TExtractFunc = function(lpszFile: PChar; nIconIndex, cxIcon, cyIcon: integer; phicon: PHANDLE; piconid: PDWORD; nicon, flags: DWORD): DWORD; stdcall;
var
  hIcon: THandle;
  nIconId: DWORD;
  Icon: TIcon;
  PrivateExtractIcons: TExtractFunc;
  hUserDll: THandle;
begin
 result:= false;

 hUserDll:= LoadLibrary('user32.dll');

 PrivateExtractIcons:= GetProcAddress(hUserDll, ExtractProcName);
 if not Assigned(PrivateExtractIcons) then exit;
 //extract a icoSize x icoSize  icon where icoSize is one of 256,128,64,48,32,16

 if PrivateExtractIcons(Pchar(exeFilename), 0, icoSize, icoSize, @hIcon, @nIconId, 1, LR_LOADFROMFILE) <>0 then
 begin
  try
   Icon:=TIcon.Create;
   try
    Icon.Handle:=hIcon;
    Icon.SaveToFile(icoOutFileName);
    result := true;
   finally
    Icon.Free;
   end;
  finally
   DestroyIcon(hIcon);
  end;
 end;
end;

// ---------------------------------------------------------------//

procedure TForm1.Button1Click(Sender: TObject);
var OutFile: string;
const FilePath = 'D:\Apps\GIMPPortable\GIMPPortable.exe';
begin
 OutFile:= 'C:\Users\<User>\Desktop\Icon'+inttostr(Random(500))+'.ico';
 ExtractIcons(FilePath, OutFile, 256);
end;

procedure TForm1.Button2Click(Sender: TObject);
var Icon: TIcon;
    OutFile: string;
const FilePath = 'D:\Apps\GIMPPortable\GIMPPortable.exe';
begin
 Icon:= TIcon.Create;
 GetIconFromFile(FilePath, 0, Icon);
 OutFile:= 'C:\Users\<User>\Desktop\Icon'+inttostr(Random(500))+'.ico';
 if not Icon.Empty then
  Icon.SaveToFile(OutFile);
 Icon.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Randomize;
end;

Hat jemand eine Ahnung, wie ich das Icon 1:1 extrahieren kann, ohne (großen) Qualitätsverlust?

Viele Grüße
Littleben


mandras - So 02.12.12 18:44

http://stackoverflow.com/questions/3813845/how-can-i-extract-an-image-of-a-specific-size-from-an-icon


LittleBen - So 02.12.12 19:27

Wenn du mir mit dem Links sagen willst, dass ich ExtractIconEx benutzen soll: Funktioniert aucht nicht


mandras - So 02.12.12 23:36

nein, tut es nicht.
Ich habe einige Zeit mit dem Problem verbracht, komme aber auch nicht zu einer Lösung.
Im Augenblick ärgert mich die nicht korrekte Anbindung der entspr. Deklarationen in Delphi an die Win32 API.


Martok - So 02.12.12 23:58

So aus'm Gedächtnis würde ich behaupten, dass TIcon nur die beiden kleinen Auflösungen in 16 Farben kann, oder?

Wäre sicherlich mal interessant, das Ding in funktionierend zu haben. Auch die Masken-Behandlung ist ja doch etwas seltsam.


bummi - Mo 03.12.12 01:19

hier gibt es einen gegf. hilfreichen Beitrag zu diesem Thema
http://www.delphipraxis.net/170682-laden-und-speichern-von-icons-icon-parser-fuer-icon-dateien-oder-resourcen.html


LittleBen - Di 04.12.12 20:27

Danke Bummi. Durch den Link bin ich auf folgende Bibliothek gekommen: http://www.torry.net/vcl/graphics/icons/icotools.zip Das ist die Lösung :)