Seite 1 von 1

AddImageFrame() Problem

Verfasst: 29.03.2018 14:16
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.

Re: AddImageFrame() Problem

Verfasst: 29.03.2018 15:39
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

Re: AddImageFrame() Problem

Verfasst: 29.03.2018 16:55
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.

Re: AddImageFrame() Problem

Verfasst: 29.03.2018 17:34
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)

Re: AddImageFrame() Problem

Verfasst: 29.03.2018 19:46
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.

Re: AddImageFrame() Problem

Verfasst: 29.03.2018 20:29
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.

Re: AddImageFrame() Problem

Verfasst: 29.03.2018 22:54
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.

Re: AddImageFrame() Problem

Verfasst: 04.04.2018 09:32
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

Re: AddImageFrame() Problem

Verfasst: 04.04.2018 12:37
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.