![]() |
[LoadPNGIntoBitmap32] Fehler beim Laden einer PNG
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo, Community! :dp:
Auch ich habe mal wieder ein Problem, und zwar folgendes: Für ein Spiel habe ich eine Klasse TTileSkin, die das Sprite des Tiles sowie einige Zusatzinformationen enthält. Das Sprite ist ein TBitmap32. Für das Speichern werden die Sprites mit der PNGImage-Komponente komprimiert und in eienr Datei gespeichert. Das klappt auch sehr gut, es wird ein gültiges PNG gespeichert. Beim Laden werden dann die PNGs wieder ausgelesen - Soweit alles okay. Bei einem bestimmten PNG tritt jedoch ein Fehler auf, wenn ich es anschließend wieder mit der LoadPNGIntoBitmap32-Funktion in ein TBitmap32 laden will:
Code:
Markiert ist die zeile 4809 der Unit PNGImage (ImageData[i] := pRGBQuad(@ImageSource[i2 * 3])^), das ist in der procedure TPngObject.DrawPartialTrans(DC: HDC; Rect: TRect). Die wird von TBitmap32.Assign(TPNGObject) aufgerufen.
---------------------------
Benachrichtigung über Debugger-Exception --------------------------- Im Projekt TileEditor.exe ist eine Exception der Klasse EAccessViolation mit der Meldung 'Zugriffsverletzung bei Adresse 0047FF01 in Modul 'TileEditor.exe'. Lesen von Adresse 017A9000' aufgetreten. --------------------------- Anhalten Fortsetzen Hilfe --------------------------- Ich bin echt ratlos, weil das ganze mit 7 von 8 Bildern tadellos funktioniert. Und das eine Bild, das nicht funktioniert, wurde ja von der Komponente selbst erzeugt und wird auch anstandslos geladen. Testweise habe ich es auch nochmal direkt nach dem Laden mit SaveToFile abgespeichert, heraus kam ein absolut valides PNG. Hier noch mein eigener Code. Ich nutze der Einfachkeit halber TRAKBinaryStreamData von Richard Kaspar. (Mit der erzeugten Datei ist aber ebenfalls alles in Ordnung)
Delphi-Quellcode:
Ich habe die PNGs angehängt.
// Diese Funktion habe ich selbst geschrieben, um eine beliebige Grafik in ein TBitmap32 zu laden.
function LoadGraphicIntoBitmap32(const dest: tBitmap32; const src: tGraphic): boolean; var dummy: boolean; begin result := false; if src is TBitmap then begin dest.Assign(src); result := true; end else if src is TPNGObject then begin LoadPNGIntoBitmap32(dest,tpngobject(src),dummy); result := true; end else if src is TGraphicClass then begin dest.SetSize(src.Width,src.height); dest.Canvas.Draw(0,0,src); dest.ResetAlpha(255); result := true; end; end; // Diese Methode lädt den TileSkin aus einem TRAKBinaryTag procedure TSgTileSkin.LoadFromTag(Tag: TRAKBinarytag); var lgraphic: tGraphic; begin name := tag.AttributeAsString('n',''); // Name laden (irrelevant) collisionmap.LoadFromTag(tag.FindFirstTag('cm')); // Kollisionsmap laden (irrelevant) if assigned(image) then freeandnil(image); // Ggf. das alte Bitmap löschen begin Image := tbitmap32.Create; // Internes Bitmap32 wird erzeugt lGraphic := tpngobject(TRakBinaryPicture(Tag.AttributeByName('img')).graphic); lGraphic.SaveToFile('c:\hsadhgjh.png'); // Hier habe ich es testweise gespeichert -> kein Fehler, gültiges PNG if not LoadGraphicIntoBitmap32(image, lGraphic) then // Wenn das Bild nicht geladen werden konnte begin freeandnil(Image); // Image freigeben Exception.CreateFmt('Nicht unterstütztes Format (%s)', [TRakBinaryPicture(Tag.AttributeByName('img')).Graphic.ClassName]); // exception schmeißen end; end; lines.LoadFromTag(tag.FindFirstTag('l')); // Spezielle Vektordaten (irrelevant) end; Ich hoffe, wenigstens einer konnte mir folgen :pale: ich kann eifnach nicht erklären... Danke im Voraus |
Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG
*push*
|
Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG
der einzige Unterschied der mir auffällt ist, dass das 1. Bild 3kb groß ist und das andere 7kb groß ist
|
Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG
Ja, das ist mir auch aufgefallen, aber das wird wohl daran liegen, dass das Bild neu (wahrscheinlich mit höherer Kompressionsrate) komprimiert wird, wenn es gespeichert wird.
edit: Ich hab gerade mal versucht, dass Bild, bei dem der fehler auftritt (*kryptischername*.png) direkt in meinem Editor für die Liste zu laden - hierbei tritt kein fehler auf. Zur Erklärung: Die Bilder sind mit Photoshop aus einem Tileset ausgeschnitten und einzeln abgespeichert. Für das Spiel speichere ich die alle in eine Liste, zusammen mit Zusatzinfos etc. dafür habe ich mir einen "Tilelisteditor" geschrieben. Dort kann ich neue Einträge zu einer Datei hinzufügen, ein Bild laden und zuweisen, und Bilder löschen. Wenn ich nun ein PNG-Bild über den Editor in die Liste hineinlade, geht alles glatt. Nachdem die Liset gespeichert wurde, und das Bild wieder geladen werden soll, kommt der merkwürdige Fehler. Ich verstehe das nicht, weil die Datei ja absolut gültig ist. Selbst das Laden des Bildes AUS DER Datei, das ich ja abgespeichert habe schlägt im Editor nicht fehl, obwohl dieser mit der gleichen procedure arbeitet. Und das tritt immer nur bei diesem einen Bild auf o_O edit²: Und jetzt kommts nochmal: WTF? Ich die Liste, in die ich eben testweise das "fehlerhafte" Bild geladen habe mal abgespeichert und wieder geladne? Was passiert?! KEIN Fehler! Ich versteh das nicht! Ich habe eine andere Datei, bei der ich das Quell-PNG in den Editor geladen und abgespeichert habe, aber da TRITT der Fehler auf! edit³: Die Listendateien sind tatsächlich unterschiedlich. Die funktionierende ist 4.6, die andere 4.1 kByte groß. Das macht doch keinen Sinn - wenn ich die Datei vorher in dein TBitmap32 lade, anschließend in ein neu erzeugtes PNG und mich der gleichen procedure abspeichere, können doch nicht zwei unterschiedliche Dateien herauskommen o___O. Zumal die Datei aus der 4.1 kByte großen Liste ja hier angehängt ist und ebenfalls funktioniert. W T F? |
Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG
*schieb*
Ich habe wirklich keine Idee, woran das liegen könnte, und das komtm selten bei mir vor, normalerweise finde ich den Fehler. Ich würde den gesamten Code ja mal anhängen, aber leider ist der über die Wochen schon so schrecklich lang geworden und nur spärlich kommentiert :pale: Hier erstmal der Code zum Speichern, falls es hilft.
Delphi-Quellcode:
procedure TSgTileSkin.SaveToTag(Tag: TRAKBinarytag);
var lPNG: tpngobject; begin TRAKBinaryDouble.AddToTag(Tag,'w',width); TRAKBinaryDouble.AddToTag(Tag,'h',height); TRAKBinaryAnsiString.AddToTag(tag,'n',Name); if assigned(image) then begin lPNG := tpngobject.CreateBlank(COLOR_RGBALPHA,8,image.Width,image.height); // lPNG := TPNGObject.Create; LoadBitmap32intoPNG(lPNG,image); TRakBinaryPicture.AddToTag(Tag,'img',lPNG); freeandnil(lPNG); end; Collisionmap.SaveToTag(Tag.AddTag('cm')); lines.SaveToTag(tag.AddTag('l')); end; |
Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG
Habt ihr keine Lust, keine Idee oder versteht man es nicht? :/
|
Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG
Das bild was nicht geht ist ein 32Bit PNG das andere ein 24Bit
|
Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG
Ah, das klingt interessant. Ich dachte bisher PNGs wären automatisch 32 Bit.
Ich guck mal, ob die, die funzen 32 bittig sind. Vielen Dank schonmal! //edit: das ist tatsächlich das einzige mit 24 Bit. Vielen Dank! Jetzt muss ich mir nur noch was überlegen, um die automatisch zu konvertieren... (könnte natürlich auch das Bild umkodieren, aber ich will lieber die sichere Lösung). edit2: Zu früh gefreut. Das mit Photoshop im 32Bit-Format abgespeicherte PNG meckert nun auch, wenn ich es im Tileeditor lade :wall: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:50 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz