Page 1 of 1

limited on images or drawing?

Posted: Thu Jul 01, 2010 8:31 am
by J. Baker
I've created a motion blur script that can basically take 100 sublayer images and create a single motion blurred frame. The problem is though, once it gets to image 2078, it crashes every time on the following line...

Code: Select all

DrawAlphaImage(ImageID(AlphaLayer), 0, 0, Alpha.f) ;Stops in the middle of Frame 21 when rendering, The specified #Image is not initialized
But this line works fine for images 1 to 2077. I've gone and debugged every line I can and all seems fine.

It's a pretty routine script. Load 100 images, render to single frame, free images and loop until done. Any ideas?

Re: limited on images or drawing?

Posted: Thu Jul 01, 2010 9:24 am
by blueznl
Can you buid a snippet?

Re: limited on images or drawing?

Posted: Thu Jul 01, 2010 9:30 am
by J. Baker
blueznl wrote:Can you buid a snippet?
Here it is. Had to do some cleaning.

Code: Select all

UsePNGImageDecoder()
UsePNGImageEncoder()

If OpenWindow(0, 0, 0, 400, 165, "Motion Blur", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
  
    TextGadget(1, 10, 10, 360, 20, "Image Folder")
    StringGadget(2, 10, 30, 360, 20, "")
    ButtonGadget(3, 370, 30, 20, 20, "...")
    
    TextGadget(4, 10, 60, 360, 20, "Output Folder")
    StringGadget(5, 10, 80, 360, 20, "")
    ButtonGadget(6, 370, 80, 20, 20, "...")
    
    TextGadget(7, 10, 120, 100, 20, "Layers Per Frame")
    StringGadget(8, 100, 115, 40, 20, "100")
    
    ButtonGadget(9, 340, 115, 50, 20, "Render")
    
    CreateStatusBar(10, WindowID(0))
    AddStatusBarField(200)
    AddStatusBarField(200)
    StatusBarText(10, 0, "Total Images: 0")
    StatusBarText(10, 1, "Frames Rendered: 0")
    
    ImageIDs = 0
    FrameNumber = 0
    
   Repeat
     Event = WaitWindowEvent()
      Select Event
       Case #PB_Event_Gadget
        Select EventGadget()

         Case 3 ;Select Image Folder
                InitialPath$ = "C:\"
                InputImages$ = PathRequester("Load images...", InitialPath$)
                
                SetGadgetText(2, InputImages$)
                
                ExamineDirectory(0, InputImages$, "*.png")
                 While NextDirectoryEntry(0)
                
                   ImageIDs +1
                   
                   StatusBarText(10, 0, "Counting Images: " + Str(ImageIDs))
                
                 Wend
                FinishDirectory(0)
                 
                 StatusBarText(10, 0, "Total Images: " + Str(ImageIDs))  
           
         Case 6 ;Select Output Folder
                InitialPath$ = "C:\"
                OutputImages$ = PathRequester("Save images...", InitialPath$)
                
                SetGadgetText(5, OutputImages$)
                
         Case 9 ;Render
                
             ExamineDirectory(1, InputImages$, "*.png")
                
             For Refresh = (ImageIDs / Val(GetGadgetText(8))) To 1 Step -1
                
                Alpha.f = 255 / Val(GetGadgetText(8))
           
                AlphaFade.f = Alpha.f / Val(GetGadgetText(8))
                
                AlphaMinus = Val(GetGadgetText(8))
                
                FramesToRender = (ImageIDs / Val(GetGadgetText(8))) +1
                
                NoAlpha = 1
                
                NewImage = 0
                
                Layers = 0
                
                For AlphaLayer = ImageIDs To 1 Step -1
                  
                   NextDirectoryEntry(1)
                    ImageName$ = DirectoryEntryName(1)
                   
                    LoadImage(AlphaLayer, InputImages$ + ImageName$)

                   W = ImageWidth(ImageIDs)
                   H = ImageHeight(ImageIDs)
                  
                  If NewImage = 0

                  CreateImage(0, W, H, 32 | #PB_Image_Transparent)
                   StartDrawing(ImageOutput(0))
                    DrawingMode(#PB_2DDrawing_Default)
                    NewImage +1
                  EndIf
                    
                       If NoAlpha = 1
                         DrawAlphaImage(ImageID(AlphaLayer), 0, 0, 255)
                       Else
                         DrawAlphaImage(ImageID(AlphaLayer), 0, 0, Alpha.f) ;Stops at Frame 20 when rendering, The specified #Image is not initialized
                       EndIf
                       
                       AlphaMinus -1
                       Alpha.f = AlphaFade.f * AlphaMinus
                       
                      Layers +1
                      NoAlpha +1
                    
                    If Layers = Val(GetGadgetText(8))
                        FrameNumber +1
                         FramesToRender -1
                         SaveImage(0, OutputImages$+Str(FramesToRender)+".png", #PB_ImagePlugin_PNG, 32)
                          StatusBarText(10, 1, "Frames Rendered: " + Str(FrameNumber))
                           StopDrawing()
                            FreeImage(0)
                           
                         For FreeImages = ImageIDs To ImageIDs - Val(GetGadgetText(8))
                           FreeImage(FreeImages)
                         Next FreeImages
                         ImageIDs - Val(GetGadgetText(8))

                       Break
                         
                     EndIf
                    
                  Next AlphaLayer
                
                Next Refresh 
                
              FinishDirectory(1)
          
       EndSelect
     EndSelect
   
   Until Event = #PB_Event_CloseWindow
 
EndIf

Re: limited on images or drawing?

Posted: Thu Jul 01, 2010 9:55 am
by srod
Difficult to test this, but a quick glimpse at your code and you are not testing whether each .png is successfully loaded before you then proceed with using the newly loaded image! Perhaps the 2078 image load is failing for some reason?

Ideally then you should add some code to test that each .png is loaded successfully. You could also employ an IsImage() to check that you have loaded an image correctly before then trying to draw it onto another image.

But my real question is.... why are you loading all images? Why not load the images one at a time? Load a .png, check it loaded correctly, make use of it as appropriate, free it, and then load the next one etc.

Re: limited on images or drawing?

Posted: Thu Jul 01, 2010 11:54 am
by Mr Coder
I agree with srod: every command that returns a success/fail value MUST be checked for their status. Yes, it adds code and is boring to type, but it's essential. OpenWindow, LoadImage, SaveImage, ReadFile, etc -- check them ALL for success/fail. That way, you wouldn't even need IsImage() etc, because your app should already know.

Re: limited on images or drawing?

Posted: Thu Jul 01, 2010 12:24 pm
by J. Baker
I usually do error checking when pretty much done coding. I guess because I never had too many issues before. PB has been good to me. But will do some error checking now. Oh, and yeah, I guess I could do 1 image at a time. Maybe that would solve my issue instead of loading them in groups. Thanks for your advice and will post if it still gives me some error. ;)

Re: limited on images or drawing?

Posted: Thu Jul 01, 2010 1:53 pm
by freak
You are probably running out of memory to load new images. If each image is around 1Mb in memory then 2078 images easily fill up the 2 GB you have available in a 32bit program.

Loading them one at a time (and freeing them before loading the next) should solve this.

Re: limited on images or drawing?

Posted: Thu Jul 01, 2010 2:01 pm
by J. Baker
freak wrote:You are probably running out of memory to load new images. If each image is around 1Mb in memory then 2078 images easily fill up the 2 GB you have available in a 32bit program.

Loading them one at a time (and freeing them before loading the next) should solve this.
That was my issue when I first started this. Then I made it just 100 frames at a time. But you guys are probably right, I recode it for one at a time. ;)

Re: limited on images or drawing?

Posted: Thu Jul 01, 2010 8:27 pm
by J. Baker
I now know why I loaded in bulk. Because the frames have to be rendered backwards for each key frame. Otherwise the motion blur would sit behind the object instead of being overlaid. But I think I might be able to use GrabDrawingImage() somehow. Render sub layers 1-99 on one image and 100 on another. Then hopefully combine them.