AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Bitmap manuel als icon speichern

Ein Thema von Memnarch · begonnen am 19. Jun 2012 · letzter Beitrag vom 22. Jun 2012
Antwort Antwort
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
737 Beiträge
 
#1

Bitmap manuel als icon speichern

  Alt 19. Jun 2012, 15:11
Nabend,
Also wenn ich die struktur eines Icons richtig verstanden habe, liegen in einem icon einfach nur mehrere bmaps. Vorangestellt ist eine TIconDir struktur mit einer TIconDirEntry-Liste(array)

Ok, diese strukturen sagen wieviele, welche und wo die bitmaps in der Ico datei liegen.
Nach diesen strukturen kommen dann die eigentlichen Bildinformationen.

In der MSDN steht das im falle von BMP bildern einfach die komplette BMP ohne BMPFILEHEADER geschrieben wird.
In diesem falle also eine TBitmap als stream speichern, den offset auf die stelle nach dem header setzen und diese daten hinten anhängen?

Irgendwo habe ich zumindest nen knicks, den das resultat ist eine kaputte datei -.-

MFG
Memnarch
Da man Trunc nicht auf einen Integer anwenden kann, muss dieser zuerst in eine Float kopiert werden
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#2

AW: Bitmap manuel als icon speichern

  Alt 19. Jun 2012, 16:20
sowas nützt Dir wahrscheinlich nichts?

Delphi-Quellcode:
function BitmapToIcon(Bitmap: TBitmap;Size:Integer): TIcon;
var

  IconInfo: TIconInfo;
  IconBitmap, MaskBitmap: TBitmap;
  x, y: Integer;
  TransparentColor: TColor;
begin
  Result:= TIcon.Create;
  IconBitmap:= TBitmap.Create;
  MaskBitmap:= TBitmap.Create;
  try
  IconBitmap.Width:= Size;
  IconBitmap.Height:= Size;
  IconBitmap.Canvas.StretchDraw(Rect(0, 0, Size, Size), Bitmap);
  IconBitmap.TransparentColor:= Bitmap.TransparentColor;
  TransparentColor:= IconBitmap.TransparentColor and $FFFFFF;
  
  MaskBitmap.Assign(IconBitmap);
  for y:= 0 to Size - 1 do
    for x:= 0 to Size - 1 do
      if IconBitmap.Canvas.Pixels[x, y] = TransparentColor then
        IconBitmap.Canvas.Pixels[x, y]:= clBlack;
  IconInfo.fIcon:= True;
  IconInfo.hbmMask:= MaskBitmap.MaskHandle;
  IconInfo.hbmColor:= IconBitmap.Handle;
  Result.Handle:= CreateIconIndirect(IconInfo);
  finally
  MaskBitmap.Free;
  IconBitmap.Free;
  end;
end;
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)

Geändert von Bummi (19. Jun 2012 um 20:47 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.463 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Bitmap manuel als icon speichern

  Alt 19. Jun 2012, 16:28
Sollte man nicht besser die Icon-Instanz als Parameter entgegennehmen und ein paar Ressourcenschutzblöcke einbauen?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
737 Beiträge
 
#4

AW: Bitmap manuel als icon speichern

  Alt 19. Jun 2012, 17:00
Verzeiht meine vergesslichkeit
Hatte es schon hinbekommen.
Der trick war:
Nach schreiben der dir und entry strukturen, manuel den header aufsetzen und schreiben und danach einfach die pixel reinschreiben.

Jetzt klappts und ich kann aus bmps icons generieren(multiframe inklusive)

edit: auf die Idee mit dem header selbstschreiben bin ich hierdurchgekommen:

http://www.pjhayward.net/ico.php

Hier ist mir dan auch aufgefallen wo ich den fehler in meinen entry strukturen hatte^^"
Da man Trunc nicht auf einen Integer anwenden kann, muss dieser zuerst in eine Float kopiert werden
  Mit Zitat antworten Zitat
NickelM

Registriert seit: 22. Jul 2007
Ort: Carlsberg
445 Beiträge
 
Delphi 2009 Professional
 
#5

AW: Bitmap manuel als icon speichern

  Alt 19. Jun 2012, 18:10
Naja mit Bummis Funktion habe ich es so hinbekommen:
Delphi-Quellcode:
var Icon : TIcon;
    Bitmap,TmpBitmap : TBitmap;
    IconInfo : TCursorOrIcon;
    IconRec : TIconRec;
    FileStream : TFileStream;
    BmfInfo : TBitmapInfoHeader;
    MemStream : TMemoryStream;
    X,Y : Integer;
begin
  Bitmap := TBitmap.Create;
  try
    Bitmap.LoadFromFile('C:\Users\Mario\Desktop\test_ico.bmp');
    Bitmap.PixelFormat := pf8bit;
    Icon := BitmapToIcon(Bitmap,32);
  finally
    Bitmap.Free;
  end;
    try
      MemStream := TMemoryStream.Create;
      try
        Icon.SaveToStream(MemStream); //In dem Stream ist aber eine Komplette Ico-Datei inklusive Header
Wenn du, was ich ja vermute, eine Ico-Datei mit mehreren Bitmaps machen willst musst du beide Header überschreiben
        FileStream := TFileStream.Create('C:\Users\Mario\Desktop\test_create.ico',fmCreate);
        try
          FillChar(IconInfo,SizeOf(IconInfo),0);
          IconInfo.wType := RC3_ICON;
          IconInfo.Count := 1;
          FileStream.WriteBuffer(IconInfo,SizeOf(IconInfo));
          FillChar(IconRec,SizeOf(IconRec),0);
          IconRec.Width := 32; //Header Manuel schreiben
          IconRec.Height := 32;
          IconRec.Reserved1 := 1; //Immer 1
          IconRec.Reserved2 := 8; //Pixelformat in Bits
          IconRec.DIBSize := MemStream.Size - SizeOf(IconRec) - SizeOf(IconInfo); //Größe anpassen
          IconRec.DIBOffset := FileStream.Position + SizeOf(IconRec); //Sowie Pos neusetzen
          FileStream.WriteBuffer(IconRec,SizeOf(IconRec)); //Schreiben
          FileStream.Position := IconRec.DIBOffset; //Zur Pos des Bild begins
          FileStream.WriteBuffer(Pointer(Integer(MemStream.Memory) + SizeOf(IconRec) + SizeOf(IconInfo))^,IconRec.DIBSize);
        finally
          FileStream.free;
        end;
      finally
        MemStream.free;
      end;
    finally
      Icon.free;
    end;
end;
EDIT:Sehe schon du hast es, naja aber für die Leute die es "einfacher" haben wollen.
Mann muss natürlich ein bischen umschreiben, wenn man mehrer Header reinschreiben will, aber das denk ich wäre möglich.
EDIT2: @DeddyH : So der Schönheit und der RAM-Memory-Sicherung zuliebe.
Nickel
"Lebe und denke nicht an morgen"
Zitat aus dem gleichnamigen Bollywoodfilm.

Geändert von NickelM (19. Jun 2012 um 19:00 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.463 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Bitmap manuel als icon speichern

  Alt 19. Jun 2012, 18:30
Holla die Waldfee. Hast Du mal ReportMemoryLeaksOnShutdown auf true gesetzt?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
NickelM

Registriert seit: 22. Jul 2007
Ort: Carlsberg
445 Beiträge
 
Delphi 2009 Professional
 
#7

AW: Bitmap manuel als icon speichern

  Alt 19. Jun 2012, 18:47
Ne, hab jetzt die try...finallys vergessen gehabt Passiert mal
Die könnte man noch nachtragen, falls wirklich jemand diesen Code benötigt.
Nickel
"Lebe und denke nicht an morgen"
Zitat aus dem gleichnamigen Bollywoodfilm.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.463 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Bitmap manuel als icon speichern

  Alt 19. Jun 2012, 18:50
Die könnte man noch nachtragen, falls wirklich jemand diesen Code benötigt.
Jo, das wäre nett. Hinterher meinen die Leser noch, wir schweinsen hier mit dem RAM herum
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
737 Beiträge
 
#9

AW: Bitmap manuel als icon speichern

  Alt 21. Jun 2012, 11:04
Ich muss übrigens noch einen Fehler korrigieren, der im von mir verlinkten quellcode vorkommt.
Der author dieses quelltextes lässt am ende für ein 32bit icon die 1bit alpha mask weg. Das ist aber falsch. Bei jedem DirEntry muss zur imagegröße die 1bitmask größe hinzugerechnet werden UND natürlich auch eine geschrieben werden(in diesem fall reicht einfach 0 für alles sichtbar).

Warum? Macht mal bei einer datei die mit obigem fehler kreiert wurde nen rechtsklick->show properties
oder drück entf damit der entfernen dialog mit bildvorschau aufpoppt. Dort werdet ihr hässliche schwarze punkte entdecken.

Wieso den das?
Nur weil ein icon 32bit ist und einen eigenen alphachannel hat, heißt dass nicht dass er auch von allen loadern genutzt wird. In diesem fall wird einfach die 1bit alphamask abgefragt
Da man Trunc nicht auf einen Integer anwenden kann, muss dieser zuerst in eine Float kopiert werden
  Mit Zitat antworten Zitat
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
737 Beiträge
 
#10

AW: Bitmap manuel als icon speichern

  Alt 22. Jun 2012, 09:33
Guten Morgen allereits,
Ich bin es nochmal. Ich habe ein Problem.
WIE berechne ich die Größe der 1bit alphamask?

Soweit ich weiß wird in dieser Maske für jeden pixel ein bit angekreuzt repräsentativ für sichtbar/unsichtbar.

Also dachte ich ich brauche (width*height)/8 bytes an bitmaske

Aber irgendwas stimmt nicht.

32*32/8 = 128
Gimp = 128

ok ABER:

16*16/8 = 32
Gimp = 64

24*24/8 = 72
Gimp = 96

Meine größen passen zwar exakt, resultieren aber je nach viewer(icon thumbnail preview/ bildvorschau) in einer fehlerhaften darstellung. Die Größen von Gimp erzeugen ein sauberes bild.

Ja wie komm ich den jetzt mathem,atisch auf diese Größen?
Da man Trunc nicht auf einen Integer anwenden kann, muss dieser zuerst in eine Float kopiert werden
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:20 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf