Seite 1 von 1

Image als PNG speichern

Verfasst: 16.06.2009 22:20
von Lord
Hi @all!

Typische Anfängerfrage: "Warum erhalte ich beim Abspeichern eines Images als PNG (JPEG/BMP) nur ein schwarzes Bild?"

Hintergrundinfo: Ich versuche aus mehreren (vielen) kleineren PNGs ein großes zu erstellen.
Die Anzeige auf dem Bildschirm funktioniert, nur das gespeicherte Image ist schwarz bei ansonsten korrekten Abmessungen.

Der Code dazu ist so leider nicht lauffähig, da ja die Grafikdateien fehlen.
Vielleicht ist aber ja der Fehler den ich im Code habe so offensichtlich, daß er euch gleich ins Auge springt.
Ich würde mich über Hilfe freuen.

Code: Alles auswählen

Enumeration
  #MainWindow
  #ChildWindow
EndEnumeration
Enumeration
  #Image1
EndEnumeration
Enumeration
  #Sprite
EndEnumeration

InFolder$="F:\Eigene Dateien\Historische Karten\Kartenteile\Test\"
OutFolder$="F:\Eigene Dateien\Historische Karten\Kartenteile\Test2\"

InitSprite()
UsePNGImageDecoder()
UsePNGImageEncoder()

OpenWindow(#Mainwindow,0,0,1240,1000,"Map")
AddKeyboardShortcut(#MainWindow,#PB_Shortcut_S,1); Taste 'S' zum speichern
OpenWindowedScreen(WindowID(#MainWindow),0,0,1000,1000,0,0,0)
CreateImage(#Image1, 5200, 3471,8)
CreateSprite(#Sprite,400,267,0)

; Die Grafikdateien liegen als PNG mit 8 Bit Tiefe und 400x300 Pixel vor
; Der Dateiname hat die Form XxxYyy.png
; Auf das Image werden die Teilgrafiken in x-Richtung nebeneinander und
; in y-Richtung überlappend gezeichnet.

y=0
Repeat
  x=0
  Repeat
    Datei$="X"+RSet(Str(x),2,"0")+"Y"+RSet(Str(y),2,"0")+".png"; XxxYyy.png
    LoadSprite(#Sprite,InFolder$+Datei$)
    StartDrawing(ImageOutput(#Image1))
      DisplaySprite(#Sprite,x*400,y*267)
    StopDrawing()
    FlipBuffers()
    x+1
  Until x=3; 3 zum Testen, ansonsten 13
  y+1
Until y=3; 3 zum Testen, ansonsten 15

; Bis hier ist alles so wie es sein soll

Repeat
  event=WaitWindowEvent()
  If event=#PB_Event_Menu
    If EventMenu()=1; Taste S
      SaveImage(#Image1, Outfolder$+"LinksOben.png",#PB_ImagePlugin_PNG); Erzeugt nur ein "schwarzes Loch" als Grafik
    EndIf
  EndIf
Until event = #PB_Event_CloseWindow

Verfasst: 16.06.2009 22:33
von KeyKon
DisplaySprite() Harmoniert nicht mit StartDrawing()...
Wiso nutzt du überhaupt Sprites?
So isses nämlich etwas unpraktisch, du kannst nämlich Sprites und Images auf ein Sprite anzeigen (UseBuffer() bzw DrawImage()) oder Images auf Images anzeigen (DrawImage()) aber keine Sprites auf Images anzeigen...


EDIT:
Dein DisplaySprite() im Code zeigt das Sprite nur auf dem Screen an, das ImageDrawing is da praktisch bedeutungslos...
Mein Tipp:
Machs nur mit Images und zeig die Images mittels DrawImage() auf dem großen Image an (Vorher wie dus schon machst natürlich StartDrawing(...))

Wenn du Screen brauchst machs nur mit Sprites, einfach statt dem großen Image ein großes Sprite erstellen und dann mit UseBuffer(SpriteID) auf das Sprite "umstellen" und mit den DisplaySprites anfangen (Das ganze wird dann natürlich so nicht auf dem Screen angezeigt sondern erst wenn du wieder mit UseBuffer(#PB_Default) auf den Screen umstellst...

Auch hier gilt: F1 dein Freund und Helfer ;-)

Verfasst: 16.06.2009 22:34
von Kaeru Gaman
> Vielleicht ist aber ja der Fehler den ich im Code habe so offensichtlich, daß er euch gleich ins Auge springt.

au! Bild yap, ist er.

Code: Alles auswählen

    LoadSprite(#Sprite,InFolder$+Datei$)
    StartDrawing(ImageOutput(#Image1))
      DisplaySprite(#Sprite,x*400,y*267)
    StopDrawing()
    FlipBuffers() 
ein Image ist kein Buffer
ein Display ist kein Drawing

lade die einzelbilder als Images, und benutze DrawImage.
gespeichert wird dann mit SaveImage.

wenn du sie als sprites lädst,
kannst du sie auf einen screen displayn und per GrabSprite als großes Sprite holen,
oder per UseBuffer direkt in das große Sprite displayn.
gespeichert wird das große dann mit SaveSprite.


> ; Bis hier ist alles so wie es sein soll

und das ist das Gerücht des Tages! :mrgreen:

Verfasst: 17.06.2009 18:35
von Lord
@KeyKon & @Kaeru Gaman

Danke für eure Antworten.
Ihr habt natürlich beide Recht. :)

Die Frage, warum ich überhaupt Sprites benutze, ist natürlich berechtigt.
Ich hatte zuerst auch die "ganz normale" Image-Lösung versucht.
Dabei habe ich festgestellt, daß meine Graphiken bereits beim Laden und
anschließendem Darstellen auf dem Screen eine Art Grünstich zeigen.
Die Ausgangs-PNG-Dateien beinhalten diesen Farbstich nicht (mit IrfanView und MS-Draw überprüft).
Bei der oben von mir geposteten Methode zeigte sich wenigstens die Farbverfälschung
auf dem Screen nicht, ich konnte die Graphik aber irgendwie nicht wieder abspeichern.
Deshalb mein Hilferuf.

Damit ihr das Problem nachvollziehen könnt, habe ich einen Ordner zusammengestellt,
der zuerst einmal die beiden lauffähigen Programmcodes (Image- und Spritevariante) enthält.
Zusätzlich beigelegt ist eine Orignal-PNG, die beiden mit den Programmen erzeugten
Graphikdateien und eine einfache, mit MS-Draw erzeugte Graphik, die, wenn man sie ebenfalls mit
der Imagevariante des Programms lädt und abspeichert, diese Farbverfälschung zeigt.
Die beiden Programme sind Einfachversionen ohne irgendwelche Sicherheitsabfragen.

Der Link zum gezippten Ordner: http://em.q-soft.ch/473PNG-Test.zip

Verfasst: 17.06.2009 21:38
von KeyKon
Hm, also bei mir gibts beim Image keinen Grünstich :freak:

Verfasst: 17.06.2009 21:41
von Kaeru Gaman
Lord hat geschrieben:Dabei habe ich festgestellt, daß meine Graphiken bereits beim Laden und
anschließendem Darstellen auf dem Screen eine Art Grünstich zeigen.
ein screenshot wäre hier nützlich.
könnte an deine konfiguration liegen.
hab auf jeden fall noch nicht von sowas gehört.

Verfasst: 17.06.2009 21:42
von KeyKon
Naja, in dem Zip is ja eines mit Grünstich drin, bei mir allerdings wenn ich ein Bild erzeug siehts genauso aus wie Vorher, also ohne Grünstich...

Verfasst: 17.06.2009 23:22
von Lord
Kaeru Gaman hat geschrieben:
Lord hat geschrieben:Dabei habe ich festgestellt, daß meine Graphiken bereits beim Laden und
anschließendem Darstellen auf dem Screen eine Art Grünstich zeigen.
ein screenshot wäre hier nützlich.
könnte an deine konfiguration liegen.
hab auf jeden fall noch nicht von sowas gehört.
Die Screenshots hab' ich dann mal gemacht. Wobei mir nicht so ganz klar ist, welche Art
von Konfiguration Du meinst, schließlich zeigen andere Programme und das Rendern auf
den Screen mittels Sprite bei mir die Dateien ohne Verfälschungen an.
Desweiteren konnte ich auf meinem Monitor bis jetzt noch keine Farbunstimmigkeiten
bei anderen Bildern feststellen.

Screenshot (Ausschnitt) Image:
Bild

Screenshot (Auschnitt) Sprite:
Bild

Verfasst: 18.06.2009 12:56
von Falko
Versuchs mal hiermit. Da PB bei falscher Depth problem macht, merkt man beim FullScreen()..

Ändere und erweitere das hiermit bitte. Bei mir treten die Problem auch auf, wenn ich unter Fullscreen die falsche Auflösung (Bittiefe)habe.
Also bei mir klappt dann so, Dein Beispiel aus deiner Zip.

Code: Alles auswählen

...
ExamineDesktops()
CreateImage(#Image1, 400, 300,DesktopDepth(0))
...
Gruß Falko

Verfasst: 18.06.2009 17:59
von Lord
Hallo Falko!

Danke für Deinen Hinweis.

Die Ursache für den 'Grünstich' liegt wohl tatsächlich in der Bittiefe begründet.
Ich habe das Problem hier aber zwischenzeitlich anders gelöst.
Ich lade die einzelnen Teilgraphiken als Image (400x300 bei 8 Bit), rendere sie
auf ein großes Sprite (8192x8192 bei 8 Bit) und speichere dieses Sprite dann
als PNG-Datei. Auf diese Art tritt der Fehler (?) nicht auf.
Ich habe die Image-auf-Image-Variante mit in 24 Bit und 32 Bit Tiefe eben
auch noch ausprobiert. Dabei tritt der Fehler (?) dann ebenfalls nicht auf.

Eigentlich sollte doch eine 8-Bit-PNG-Graphik auf einem 8-Bit-Image fehlerfrei
übertragbar sein? Das auslösende Moment ist nicht die Übertragung auf einen
Screen, sondern das Schreiben eines Images auf ein Image. Lasse ich den
Screen (die Darstellung) ganz außen vor und bringe das kleinere Image mittels
DrawImage() auf das größere Image und speichere dieses dann mittels SaveImage()
ab, ist der Grünstich auch vorhanden.
Lade ich eine kleine PNG-Datei in ein Image und speichere dieses dann sofort
wieder ab, ist der Fehler(?) nicht da.

Nunja, ich habe jedenfalls eine funktionierende Variante (eigentlich sind's ja jetzt
derer zwei) gefunden. Damit kann ich erstmal leben.

Danke an alle für die Hilfe. :D