AddImageFrame() Problem

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
fabulouspaul
Beiträge: 120
Registriert: 01.04.2011 21:59

AddImageFrame() Problem

Beitrag von fabulouspaul »

Hallo Gemeinde,

ich brauche mal etwas Unterstützung bei einem Feature in PB 5.62, dass ich bisher noch nicht genutzt habe: ImageFrames.
So wie ich es verstanden habe, wird mit AddImageFrame() quasi ein neues Image in den Dimensionen des ersten Images erzeugt und ein neuer laufender Index vergeben. Angesprochen werden die einzelnen Images mit SetImageFrame() aber immer mit der selben Image-Nummer.
Ich hoffe das stimmt soweit.

Für eine alternative ProgressBar-Animation habe ich 12 einzelne Images, die ich bisher über einzelne Image-Nummern in einem Array anspreche - das funktioniert.
Jetzt wollte ich mich daran machen, das ganze auf Frames umzustellen und wollte dazu zunächst die einzelnen Images als Frames unter einer Image-Nummer zusammenfassen. Dabei gibt es aber einen "Ungültigen Speicherzugriff"-Fehler beim 2. Frame (Frame 0 und 1 laufen). Hier der Code-Schnipsel:

Code: Alles auswählen

Enumeration
  #ProgressImageHandle
  #TempImageHandle
EndEnumeration

Procedure read_image_frames()
  ; *** 12 Images aus der DataSection in Frames einlesen
  
  ; 1. Image aus Bild in DataSection holen
  CatchImage(#ProgressImageHandle, ?image0)
  
  ; 2. Image aus der DataSection holen
  CatchImage(#TempImageHandle, ?image1)
  ; neuen Frame zum 1. Image hinzufügen
  AddImageFrame(#ProgressImageHandle)
  ; 2. Image in neuen Frame kopieren
  CopyImage(#TempImageHandle, #ProgressImageHandle)
  FreeImage(#TempImageHandle)
  
  ; 3. Image aus der DataSection holen
  CatchImage(#TempImageHandle, ?image2)
  AddImageFrame(#ProgressImageHandle)        ; <--- Hier gibt es den ungültigen Speicherzugriff
  CopyImage(#TempImageHandle, #ProgressImageHandle)
  FreeImage(#TempImageHandle)
  
  ; 4. Image aus der DataSection holen
  CatchImage(#TempImageHandle, ?image3)
  AddImageFrame(#ProgressImageHandle)
  CopyImage(#TempImageHandle, #ProgressImageHandle)
  FreeImage(#TempImageHandle)
  
  ; 5. Image aus der DataSection holen
  CatchImage(#TempImageHandle, ?image4)
  AddImageFrame(#ProgressImageHandle)
  CopyImage(#TempImageHandle, #ProgressImageHandle)
  FreeImage(#TempImageHandle)
  
  ; 6. Image aus der DataSection holen
  CatchImage(#TempImageHandle, ?image5)
  AddImageFrame(#ProgressImageHandle)
  CopyImage(#TempImageHandle, #ProgressImageHandle)
  FreeImage(#TempImageHandle)
  
  ; 7. Image aus der DataSection holen
  CatchImage(#TempImageHandle, ?image6)
  AddImageFrame(#ProgressImageHandle)
  CopyImage(#TempImageHandle, #ProgressImageHandle)
  FreeImage(#TempImageHandle)
  
  ; 8. Image aus der DataSection holen
  CatchImage(#TempImageHandle, ?image7)
  AddImageFrame(#ProgressImageHandle)
  CopyImage(#TempImageHandle, #ProgressImageHandle)
  FreeImage(#TempImageHandle)
  
  ; 9. Image aus der DataSection holen
  CatchImage(#TempImageHandle, ?image8)
  AddImageFrame(#ProgressImageHandle)
  CopyImage(#TempImageHandle, #ProgressImageHandle)
  FreeImage(#TempImageHandle)
  
  ; 10. Image aus der DataSection holen
  CatchImage(#TempImageHandle, ?image9)
  AddImageFrame(#ProgressImageHandle)
  CopyImage(#TempImageHandle, #ProgressImageHandle)
  FreeImage(#TempImageHandle)
  
  ; 11. Image aus der DataSection holen
  CatchImage(#TempImageHandle, ?image10)
  AddImageFrame(#ProgressImageHandle)
  CopyImage(#TempImageHandle, #ProgressImageHandle)
  FreeImage(#TempImageHandle)
  
  ; 12. Image aus der DataSection holen
  CatchImage(#TempImageHandle, ?image11)
  AddImageFrame(#ProgressImageHandle)
  CopyImage(#TempImageHandle, #ProgressImageHandle)
  FreeImage(#TempImageHandle)
EndProcedure
Entweder ist es ein banaler Fehler und ich bin gerade zu blind ihn zu finden oder ich verstehe das Konzept nicht richtig.
fabulouspaul
Beiträge: 120
Registriert: 01.04.2011 21:59

Re: AddImageFrame() Problem

Beitrag von fabulouspaul »

Ich habe noch einmal etwas experimentiert... beim Kopieren eines Images in ein anderes scheint was mit den Frames nicht zu funktionieren. ...vielleicht ist das ein Bug in PB?

Code: Alles auswählen

EnableExplicit

UsePNGImageDecoder()

Enumeration 
  #Temp_image
  #MultiFrameImage
EndEnumeration

If CatchImage(#Temp_image, ?image0) = 0
  Debug "Error loading Image0 to Temp_image"
Else
  Debug "Image0 loaded..."
  If CopyImage(#Temp_image, #MultiFrameImage) = 0
    Debug "Error copying Temp_image to MultiFrameImage"
  Else
    Debug "Temp_image copied to MultiFrameImage..."
    Debug "Frames in Temp_image     : " + Str(ImageFrameCount(#Temp_image))
    Debug "Frames in MultiFrameImage: " + Str(ImageFrameCount(#MultiFrameImage))    ; <--- 0 Frames ???
    Debug "Saving MultiFrameImage... just for checking the contents..."
    SaveImage(#MultiFrameImage, "D:\test0.bmp")      ; <--- das gespeicherte Image hat trotz 0 Frames den korrekten Inhalt
    
    Debug "Delete Temp_image, add frame to MultiFrameImage..."
    FreeImage(#Temp_image)
    AddImageFrame(#MultiFrameImage)        ; <--- "ungültiger Speicherzugriff" (vermutlich logisch bei 0 Frames s.o.)
    
    Debug "Frames in Temp_image     : " + Str(ImageFrameCount(#Temp_image))
    Debug "Frames in MultiFrameImage: " + Str(ImageFrameCount(#MultiFrameImage))
    
    If CatchImage(#Temp_image, ?image1) = 0
      Debug "Error loading Image0 to Temp_image"
    Else
      If CopyImage(#Temp_image, #MultiFrameImage) = 0
        Debug "Error copying Temp_image to MultiFrameImage"
      Else
        Debug "Temp_image copied to MultiFrameImage..."
        Debug "Frames in Temp_image     : " + Str(ImageFrameCount(#Temp_image))
        Debug "Frames in MultiFrameImage: " + Str(ImageFrameCount(#MultiFrameImage))
        Debug "Saving MultiFrameImage... just for checking the contents..."
        SaveImage(#MultiFrameImage, "D:\test1.bmp")    
        
        Debug "Delete Temp_image, add frame to MultiFrameImage..."
        FreeImage(#Temp_image)
        AddImageFrame(#MultiFrameImage)    
        
        Debug "Frames in Temp_image     : " + Str(ImageFrameCount(#Temp_image))
        Debug "Frames in MultiFrameImage: " + Str(ImageFrameCount(#MultiFrameImage))
      EndIf
    EndIf
  EndIf
EndIf

End

DataSection
  image0:
  IncludeBinary "IMG00000.png"
  image1:
  IncludeBinary "IMG00001.png"
EndDataSection
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Re: AddImageFrame() Problem

Beitrag von Bisonte »

Ich denke mal das hat was mit GIF Animationen zu tun und das ist nur unglücklicherweise nicht in der Hilfe erwähnt.

Dann kann ich mir vorstellen, dass es auch nur mit GIF's oder GIFAnims funktioniert.
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: AddImageFrame() Problem

Beitrag von ccode_new »

Bisonte hat wie so oft natürlich recht.

GIF-Decoder ist hier das Stichwort.

Alles Andere ist nicht für Multi-Frames ausgelegt. (Außer Vector-SVG vielleicht, aber nicht unterstützt)
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
fabulouspaul
Beiträge: 120
Registriert: 01.04.2011 21:59

Re: AddImageFrame() Problem

Beitrag von fabulouspaul »

@bisonte & ccode_new: Danke für die Antwort!

Ich denke auch, dass die Frame-Funktionalität ihren Ursprung im GIF hat, aber per Trial & Error ist es mir gelungen, auch ohne GIF die Frames zum laufen zu bringen.
Der Trick ist, die Images nicht in einen Frame zu kopieren (CopyImage()), sondern sie hineinzu"zeichnen" (DrawImage()).

Wenn man den Code so ändert:

Code: Alles auswählen

  ; 1. Image aus Bild in DataSection holen
  CatchImage(#ProgressImageHandle, ?image0)
  
  ; 2. Image hinzufügen
  CatchImage(#TempImageHandle, ?image1)  
  AddImageFrame(#ProgressImageHandle)
  StartDrawing(ImageOutput(#ProgressImageHandle))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  DrawImage(ImageID(#TempImageHandle), 0, 0, ImageWidth(#TempImageHandle), ImageHeight(#TempImageHandle))
  StopDrawing()
  FreeImage(#TempImageHandle)
  ...
funktioniert es! Da meine Images transparent sind musste ich nur noch den Drawingmode auf AlphaBlend setzen.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: AddImageFrame() Problem

Beitrag von ccode_new »

Ich habe mal noch eine Idee.

Den gesamten Speicher von Bild1 (1. Frame) wird in einen großen vorher festgelegten Speicherbereich kopiert.
(BildZeiger = AllocateMemory(Größe der gesamten Bilder)
Dann wird nach BildZeiger+MemorySize(Bild1) das 2. Bild eingefügt und so weiter.

Damit könnte man alle Bilder hintereinander in ein "BIGImage" speichern.

Für dieses "BIGIMage" müsste man sich nur noch eine Auslesefunktion basteln.
Diese Funktionen solle nach dem jeweiligen Speicheroffset die einzelnen Bilder auslesen und erstellen.

Alles nur so irrer Gedanke.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
fabulouspaul
Beiträge: 120
Registriert: 01.04.2011 21:59

Re: AddImageFrame() Problem

Beitrag von fabulouspaul »

Das könnte man machen ccode_new, aber jetzt da es mit Frames geht, finde ich es eleganter über den Frame-Index auf die einzelnen Images zugreifen zu können.

Falls es jemanden interessiert, ich habe ein kleines Programm nebst den Images hier Datei von filehorst.de laden abgelegt.
Wird keinen Schönheitswettbewerb gewinnen, aber zeigt generell mal die Funktion.
Micha122
Beiträge: 248
Registriert: 02.10.2011 14:45
Wohnort: Sinzig
Kontaktdaten:

Re: AddImageFrame() Problem

Beitrag von Micha122 »

Hallo fabulouspaul,
die ProgressBar sieht echt gut aus und ist einfach zu realisieren. :allright:

Lediglich die Event-Schleife würde ich anders gestalten.
Ich würde da eher mit AddWindowTimer() und EventTimer() arbeiten.
Aber letztendlich hat jeder seinen eigenen Stiel.

Grüße, Michael
Barcodes for PureBasic - http://micha122.bplaced.net/
fabulouspaul
Beiträge: 120
Registriert: 01.04.2011 21:59

Re: AddImageFrame() Problem

Beitrag von fabulouspaul »

Hallo Michael,

stimmt, über einen WindowTimer ist es eleganter, aber mir ging es hauptsächlich ja darum zu zeigen, was ich über das Arbeiten mit Frames herausgefummelt habe. :)

Eine Erweiterung wäre auch noch, in jedem Frame eine Anzeigedauer zu hinterlegen und in der anzeigenden Schleife diese Information zu nutzen.

Was die animierte Grafik selber angeht habe ich die nur schnell mit einem kleinen PB-Programm zusammengeschraubt, da gibt es schönere (GIF-)Animationen im Web, aber da muss man dann auch darauf achten, kein Copyright zu verletzen :P
Bei einem animierten GIF muss man sich dann auch nicht darum sorgen die einzelnen Bilder in Frames zu packen.
Antworten