Icon pixelfrei
Hi,
ich lese mit einer Funktion Icons von Programmen aus und zeichne sie mit Canvas. Nun habe ich aber ziemlich viele Pixel. Kann man das irgendwie wegbekommen ? Ich habe bis jetzt zu dem Thema nur einen brauchbaren (so schien es am Anfang...) Thread gefunden, der aber keine Lösung enthielt. AntiAliasing wird wohl nötig sein. Habe zu dem Thema aber wirklich fast nichts gefunden. |
Re: Icon pixelfrei
Nun ja. Wenn du Icon/Bilder ausliest es wohl zu erwarten, dass du Pixel bekommst, oder? Den konnte ich mir nicht verkneifen. :P
Ich kann mir darunter allerdings gerade nicht viel vorstellen. Evtl solltest du mal ein Bild posten wo man das Problem sehen kann. |
Re: Icon pixelfrei
Was er will ist Kantenglättung... Bei Antialiasing wird das Bild erst z.b. 2x so groß gerechnet und dann auf Zielgröße verkleinert. Damit verschwinden die Pixelkanten.
|
Re: Icon pixelfrei
Dessen bin ich mir durchaus bewusst. Aber mir stellt sich die Frage was das mit Icons zu tun hat? Außer höchsten 32x32 Icons auf 16x16 zu rechnen. Was aber kein AntiAliasing ist. Das ist aber genau das was ich in Erfahrng bringen wollte.
|
Re: Icon pixelfrei
|
Re: Icon pixelfrei
Liste der Anhänge anzeigen (Anzahl: 2)
AntiAliasing hat hier aber nicht viel gebracht. Schaut euch vorallem die beiden obersten Icons an, der weiße Mist in der Mitte muss auf jeden Fall weg. Habe zwei verschiedene Algos getestet:
|
Re: Icon pixelfrei
Das sieht für mich eher danach aus, als gäbe es da ein Problem mit der Transparenz bzw. dem Alpha-Kanal in den Icons.
|
Re: Icon pixelfrei
Delphi-Quellcode:
So hole ich mir das Icon. Das Bild auf das ich es zuweise hat Transparent auf True.
function GetIcon(filename : String; IconIndex: Integer) : TBitmap;
var NumberOfIcons : Integer; Ico : TIcon; begin NumberOfIcons := ExtractIcon(hInstance, PChar(Filename), UINT(-1)); Ico := TIcon.Create; if (Ico <> nil) and (NumberOfIcons > -1) then Ico.Handle := ExtractIcon(hInstance, PChar(Filename), IconIndex); Result := TBitmap.Create; with Result do begin Width := Ico.Width; Height := Ico.Height; Canvas.Draw(0, 0, Ico); end; Ico.Free; end; |
Re: Icon pixelfrei
Bitte nicht AntiAliasing mit stumpfen Weichzeichnem verwechseln. Nur weil die Methode Antialiasing heiß bedeutet das nicht, dass die auch gleiches tut. Das ist ein Trugschluss. Und in den Fall könnte es von richtigem AntiAlising nicht weiter entfernt sein. Okay die Kanten sind weich aber der Recht ist auch matschig.
Nils_13: Das Zauberwort heißt Alphakanal. Seit Windows XP können Icons 24 Bit Farbtiefe enthalten und einen 8Bit Alphakanal. In deinem Fall wird aus dem 8 Bit Alphakanal eine 1 Bit Maske. Das ist aber nicht so gut, denn dadurch entstehen eben solche Kanten. Wie beim FF. Schau dir mal die Funktion GetIconInfo an. Du musst du das Handle des Icons übergeben und bekommst eine Struktur in der 2 Bitmaps enthalten sind. Ein mal das Normale RGB Bild und ein Mal die Maske. Die Maske sollte richtige 8Bit Transparenz enthalten. Diese muss du beim Zeichnen des Icons berücksichtigen. Und dabei darfst du eigenschaft Tranzparent des TBitmaps nicht benutzen. Du musst das Bild richtig blenden. Dann werden sie auch so aussehen wie sie sollen. |
Re: Icon pixelfrei
Habe eine Funktion gefunden. Das Ergebnis sieht zwar besser aus, aber nicht gut genug. Es werden die weiten Pixel geschwärzt. Könnte man anstelle von Schwarz nicht einfach die Hintergrundfarbe nehmen und es wäre alles flüssig ?
Delphi-Quellcode:
function IconToBitmap(const IconHandle : HIcon) : TBitmap;
var IcoInfo : TIconInfo; Mask : TBitmap; X, Y : Word; begin Mask := nil; Result := nil; if not GetIconInfo(IconHandle, IcoInfo) then Exit; try try Result := TBitmap.Create; Result.Handle := IcoInfo.hbmColor; Result.PixelFormat := pf32bit; Mask := TBitmap.Create; Mask.Handle := IcoInfo.hbmMask; Mask.PixelFormat := pf32bit; for X := 0 to Result.Width-1 do for Y := 0 to Result.Height-1 do pRGBALine(Result.Scanline[Y])^[X].rgbReserved := not pRGBALine(Mask.Scanline[Y])^[X].rgbRed; except FreeAndNil(Result); end; finally if Assigned(Mask) then Mask.Free; end; end; function GetIcon(filename : String; IconIndex: Integer) : TBitmap; var NumberOfIcons : Integer; Ico : TIcon; begin NumberOfIcons := ExtractIcon(hInstance, PChar(Filename), UINT(-1)); Ico := TIcon.Create; if (Ico <> nil) and (NumberOfIcons > -1) then Ico.Handle := ExtractIcon(hInstance, PChar(Filename), IconIndex); Result := IconToBitmap(Ico.Handle); Result.Canvas.Draw(0, 0, Ico); Ico.Free; end; |
Re: Icon pixelfrei
1. Das Windows-Bitmap Format was u.A. Delphi verwendet ist Äusserst bescheiden wenn es um die
Verwendung von Transparenzen geht. 2. Warum bleibst du nicht einfach bei Icons, zum Zeichnen dieser aber nur DrawIconEx() der Windows-API nutzen sonst wirds es wieder nix richtiges. 3. Willst du doch Bitmaps dan nutze die GR32 - Bitmaps die den Alphakanak unterstützen 4. Was du willst gnau machen mit die Icons ? |
Re: Icon pixelfrei
Kommt drauf an was man vor hat. Wenn man das Icon selber zeichnen kann, dann ist sicherlich DrawIconEx die beste Wahl. Allerdings wenn das ein Icon in einer Komponente sein soll, dann kommt man um Bitmaps teilweise nicht herum, da diese leider nur mit Bitmaps arbeiten. So war es zu mindest bei mir immer.
Ich hatte gerade noch mal in Quellen von mir geschaut. Dort mache ich komischer weise nichts anderes als das Icon auf ein weißes Bitmap zu zeichnen. Und dabei wurde die Transparenz automatisch mit reingerechnet. Das was du im ersten Code gemacht hattest. Nur eben direkt weißer Hintergrund und Pixelformat war pf24Bit. Allerdings dort hatte es funktioniert. Was ich etwas komisch finde. Bei dem zweiten Code müsstest du den Alphakanal direkt mit verrechnen. Denn Windows Bitmap können eigentlich kein Alphakanal. Verrechnen kannst du das in dem du für jedes Pixel die resultierende Farbe berechnest. Der Wert aus der Maske spiegelt dann die Sichtbarkeit wieder. Entweder die Hintergrundfarbe oder die des Pixels aus dem Icon. Natürlich musst du jeden Kanal seperat berechnen. |
Re: Icon pixelfrei
Hm, DrawIconEx dürfte wohl richtig sein.
Mit folgendem Code wird allerdings kein Icon mehr gezeichnet, seht ihr den Grund ?
Delphi-Quellcode:
function GetIcon(filename : String; IconIndex: Integer) : TBitmap;
begin Result := TBitmap.Create; DrawIconEx(Result.Handle, 0, 0, ExtractIcon(hInstance, PChar(Filename), IconIndex), 0, 0, 0, 0, DI_NORMAL); end; |
Re: Icon pixelfrei
:wiejetzt:
Ja. Zitat:
Code:
Sicher ist dein Code aber nicht und ob das so hinnhaut ?!
DrawIconEx([color=#ff0000]Result.Canvas.Handle[/color], 0, 0, ..., 0, 0, 0, DI_NORMAL);
|
Re: Icon pixelfrei
Habe dabei wohl gepennt. Ändert aber nichts an der Ausgabe. Meinst du mit unsicher, dass ich nicht prüfe, ob die Funktion fehlschlägt ?
|
Re: Icon pixelfrei
Hmmm. So kann das nicht gehen. Denn dein Bitmap hat gar keine Größe. Außerdem so wird das Icon gar nicht wieder freigegeben, da du das Handle ein Mal an eine Funktion übergibst und sofort vergisst.
Du solltest also wohl das Handle des Icons einem TIcon zuweisen. Mit der Größe dieses das Bitmap initialisieren. Und dann mit DrawIconEx das Icon auf das Bitmap zeichnen. PS: Bitmap als Rückgabewert halte ich persönlich auch für nicht unproblematisch. Da eine andere Stelle das Bitmap freigeben muss als die bei der es erzeugt wurde. Also ich würde es erzeigen und per const an die Methode übergeben. |
Re: Icon pixelfrei
Ich habe es gerade zusammengebaut, es wird nun wieder gezeichnet aber genauso pixelig wie vorher:
Delphi-Quellcode:
procedure GetIcon(filename : String; IconIndex: Integer; var Result : TBitmap);
var Ico : TIcon; begin Ico := TIcon.Create; Ico.Handle := ExtractIcon(hInstance, PChar(Filename), IconIndex); Result := TBitmap.Create; with Result do begin Width := Ico.Width; Height := Ico.Height; DrawIconEx(Canvas.Handle, 0, 0, Ico.Handle, 0, 0, 0, 0, DI_NORMAL); end; Ico.Free; end; |
Re: Icon pixelfrei
Benutzt du rein zufällig etwas anderes als Windows XP? Also zum Beispiel Windows 2000. Denn Windows 2000 kann noch keine Transparenzen.
Evtl schau dir auch mal an was du für Bitmaps bekommst. Also die mit GetIconInfo. Einfach mal auf Platte schreiben oder in Images darstellen. Vielleicht sind die Bilder ja schon falsch. Denn sonst sieht der Code für mich zu mindest nicht falsch aus. |
Re: Icon pixelfrei
Wenn ich das richtig verstanden habe, gibts Probleme mit dem Alpha Channel.
Probier mal das hier: Advanced Icon Klappt super. MfG MuTzE |
Re: Icon pixelfrei
Hi,
das Ergebnis sieht gut aus, aber ich verstehe nicht, was ich mit dem Ergebnis Icon.Images.Image anfangen soll. Das ist nämlich TIconImage und lässt sich nicht via Canvas zeichnen. Habe mich nochmal genauer damit beschäftigt:
Delphi-Quellcode:
Nun gibt es eine AV in der markierten Zeile der AdvancedIcon.pas:
procedure GetIcon(filename : String; IconIndex: Integer; var Result : TBitmap);
var NumberOfIcons : Integer; Ico : TIcon; Icon : TAdvancedIcon; IconLib : TIconLibrary; Image : TIconImage; begin NumberOfIcons := ExtractIcon(hInstance, PChar(Filename), UINT(-1)); Ico := TIcon.Create; if (Ico <> nil) and (NumberOfIcons > -1) then Ico.Handle := ExtractIcon(hInstance, PChar(Filename), IconIndex); Icon := TAdvancedIcon(Ico); IconLib := TIconLibrary.Create; Image := Icon.Images.Image[1]; Result := TBitmap.Create; Image.Draw(Result.Canvas, 0, 0); Ico.Free; Icon.Free; IconLib.Free; end;
Delphi-Quellcode:
Ich gehe davon aus, dass oben TAdvancedIcon(Ico) falsch ist, was müsste anstelle davon hin ? So habe ich es zumindest im Beispielcode gesehen.
function TIconImageList.GetIconImage(Index : Word) : TIconImage;
begin Result:=nil; IF Index>FCapacity Then exit; <-- Result:=FList^[Index]; end; |
Re: Icon pixelfrei
Zitat:
Ist das sowas wie der türkische Vorarbeiter aufm Bau? (Hab nix gegen Imigranten, fands nur spaßig - um evtl. Missverständnissen gleich vorzubeugen!) |
Re: Icon pixelfrei
:lol: :lol:
Ist mir gar nicht aufgefallen. Zum Thema: Hat noch jemand irgendwelche Ideen ? |
Re: Icon pixelfrei
Liste der Anhänge anzeigen (Anzahl: 1)
Moin!
Also ich hab mir echt Mühe gegeben, aber mir ist der Effekt mit den weißen Randpixeln gar nicht gelungen :mrgreen: Beim Zeichnen von Icons mach ich generell einen Bogen um VCL, aber ich habs mal mit versucht^^ Das Ergebnis meiner Spielerei, hoffe es is was brauchbares bei. MFG Sun
Delphi-Quellcode:
function IconToBitmap(const Icon:HIcon; const Color:TColor; BMP:TBitmap):Boolean;
var II:TIconInfo; begin Result:=False; If BMP=nil then Exit; If not GetIconInfo(Icon, II) then Exit; try BMP.Handle:=II.hbmColor; BMP.Canvas.Brush.Color:=Color; BMP.PixelFormat:=pf24bit; Result:=DrawIconEx(BMP.Canvas.Handle, 0, 0, Icon, BMP.Width, BMP.Height, 0, BMP.Canvas.Brush.Handle, DI_NORMAL); except end; end; procedure TForm1.FormPaint(Sender: TObject); var MyIconH:HIcon; MyIcon:TIcon; MyBMP:TBitmap; begin MyIconH:=ExtractIcon(0, 'F:\Programme\Mozilla Firefox\Firefox.exe', 0); If MyIconH<=1 then Exit; DrawIconEx(Canvas.Handle, 10, 10, MyIconH, 32, 32, 0, Brush.Handle, DI_NORMAL); MyIcon:=TIcon.Create; MyIcon.Handle:=MyIconH; Canvas.Draw(42, 10, MyIcon); MyBMP:=TBitmap.Create; IconToBitmap(MyIconH, Self.Color, MyBMP); Canvas.Draw(74, 10, MyBMP); MyIcon.Free; MyBMP.Free; end; procedure TForm1.FormCreate(Sender: TObject); begin Randomize; Color:=Random(16777216); end; |
Re: Icon pixelfrei
In OnPaint funktioniert es, aber kann man das nicht auch in eine Funktion verpacken ?
Habe es probiert, ich sehe kein Icon:
Delphi-Quellcode:
GetIcon(Pfade[Akt], 0, Bmp);
Img.Picture.Bitmap := Bmp; Bmp.Free; procedure GetIcon(filename : String; IconIndex: Integer; var Result : TBitmap); var MyIconH : HIcon; MyIcon : TIcon; MyBMP : TBitmap; begin MyIconH := ExtractIcon(0, PChar(Filename), 0); if MyIconH <= 1 then Exit; Result := TBitmap.Create; DrawIconEx(Result.Handle, 10, 10, MyIconH, 32, 32, 0, Result.Canvas.Brush.Handle, DI_NORMAL); MyIcon := TIcon.Create; MyIcon.Handle := MyIconH; Result.Canvas.Draw(42, 10, MyIcon); MyBMP := TBitmap.Create; IconToBitmap(MyIconH, clGreen, MyBMP); Result.Canvas.Draw(74, 10, MyBMP); MyIcon.Free; MyBMP.Free; end; |
Re: Icon pixelfrei
Das Du das Icon nicht siehst liegt daran, das in GetIcon mit MyIcon.Free; (auch MyIconH) freigegeben wird.
Es scheint so, als hättest Du meinen QT nicht richtig interpretiert, denn das sind 3 Möglichkeiten, von der jede einzelne funktionieren würde. Wenn Du nur vor hast die Icons irgendwo drauf zu malen, dann würd' ich mir einfach das IconHandle wo sichern um es mit DrawIconEx zu zeichnen. Somit kann man auch ganz lässig die Hintergrundfarbe ändern :mrgreen:
Delphi-Quellcode:
...
private { Private-Deklarationen } Icons:Array[0..255] of HIcon; public { Public-Deklarationen } procedure FreeIcons; procedure LoadIcons; ... procedure TForm1.FormCreate(Sender: TObject); begin Randomize; Color:=Random(16777216); LoadIcons; end; procedure TForm1.FormDestroy(Sender: TObject); begin FreeIcons; end; procedure TForm1.FormPaint(Sender: TObject); var i:Byte; begin // Icons zeichnen For i:=0 to High(Icons) do if Icons[i]>1 then DrawIconEx(Canvas.Handle, 10+(i * 32), 10, Icons[i], 32, 32, 0, Brush.Handle, DI_NORMAL); end; procedure TForm1.FormClick(Sender: TObject); begin Color:=Random(16777216); end; procedure TForm1.FreeIcons; var i:Byte; begin // Icons freigeben For i:=0 to High(Icons) do if Icons[i]>1 then DeleteObject(Icons[i]); ZeroMemory(@Icons, SizeOf(Icons)); end; procedure TForm1.LoadIcons; var i:Byte; begin FreeIcons; // Icons laden For i:=0 to High(Icons) do begin Icons[i]:=ExtractIcon(0, '%WinDir%\Explorer.exe', i); If Icons[i]<=1 then Break; end; end; |
Re: Icon pixelfrei
Ah danke. Hatte dich vorhin missverstanden. Danke! :)
Hab eine Schnapszahl (2222 Beiträge) :mrgreen: |
Re: Icon pixelfrei
( ot: tja, da muss er nu einen usgebe. :mrgreen: )
|
Re: Icon pixelfrei
Hallo,
ich habe es jetzt endlich auch geschafft ein Icon in ein Image32 zu malen :D dafür benutze ich diesen code:
Code:
Jetzt habe ich aber das Problem das ich damit nichts machen kann.
DrawIconEx(image321.Canvas.Handle, 10+(1 * 32), 10, Icons[0], 32, 32, 0, Brush.Handle, DI_NORMAL);
Wenn ich das Bild speichern möchte kommt ein 0 kB Bild heraus, wenn ich die Form verschiebe ist das Bild auch weg. kann mir jemand helfen?? |
Re: Icon pixelfrei
Zitat:
Du hast tatsächlich nur auf den Bereich des Bildschirms gemalt, der für die Darstellung dieses Steuerelements vorgesehen ist. Sobald das Steuerelement von Windows die Nachricht bekommt sich neu zu zeichnen, wird es deine Darstellung übermalen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:54 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz