Einzelnen Beitrag anzeigen

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