AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG
Thema durchsuchen
Ansicht
Themen-Optionen

[LoadPNGIntoBitmap32] Fehler beim Laden einer PNG

Ein Thema von Namenloser · begonnen am 3. Apr 2008 · letzter Beitrag vom 9. Apr 2008
Antwort Antwort
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#1

[LoadPNGIntoBitmap32] Fehler beim Laden einer PNG

  Alt 3. Apr 2008, 00:06
Hallo, Community!

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:
---------------------------
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  
---------------------------
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.

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:
// 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 habe die PNGs angehängt.

Ich hoffe, wenigstens einer konnte mir folgen ich kann eifnach nicht erklären...

Danke im Voraus
Miniaturansicht angehängter Grafiken
klotz_horz4_575.png   hsadhgjh_689.png  
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#2

Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG

  Alt 4. Apr 2008, 17:09
*push*
  Mit Zitat antworten Zitat
Benutzerbild von STS301
STS301

Registriert seit: 6. Nov 2007
668 Beiträge
 
Delphi 7 Personal
 
#3

Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG

  Alt 4. Apr 2008, 17:12
der einzige Unterschied der mir auffällt ist, dass das 1. Bild 3kb groß ist und das andere 7kb groß ist
Sebastian

ölpölp

Linux will rule the universe!!
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#4

Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG

  Alt 4. Apr 2008, 17:15
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?
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#5

Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG

  Alt 5. Apr 2008, 17:47
*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

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;
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#6

Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG

  Alt 7. Apr 2008, 15:37
Habt ihr keine Lust, keine Idee oder versteht man es nicht? :/
  Mit Zitat antworten Zitat
franktron

Registriert seit: 11. Nov 2003
Ort: Oldenburg
1.446 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#7

Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG

  Alt 7. Apr 2008, 16:01
Das bild was nicht geht ist ein 32Bit PNG das andere ein 24Bit
Frank
Tux sein Lieblingsquellcode
While anzfische<TuxSatt do begin
Fisch:=TFisch.Create; Tux.EssenFisch(Fisch); Fisch.Free;inc(anzfische); end;
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#8

Re: [LoadPNGIntoBitmap32] Fehler beim Laden einer PNG

  Alt 9. Apr 2008, 17:21
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
  Mit Zitat antworten Zitat
Antwort Antwort


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 02:50 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