I am writing a program that displays 20 (320x240)images in a window using 20 imagegadgets. I then try to replace those images with new ones, and I seem to crash after displaying 240 images. I think that is a memory problem. Is there a way to display an image on the button and then clear that memory and display a second image? I am doing that, but I think I am filling memory up and that causes the crash... I have been playing with freegadget and free_image, but it still crashes. Any help appreciated,
Thanks,
John
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The object of the program is to look through hundreds or thousands of images 20 at a time, and when one finds an interesting one, to rename it.
I am using hundreds of images so they would be hard to provide. (output from a game(wild animal) camera that has been taking pictures for months. That being said, any jpgs larger than 320x240 in the directory should be sorted, loaded, shrunk to 320x240 and displayed. As the code is shown the last 4 characters in the file name have to be ".JPG" to be recognized. That can be changed by changing the fend variable to ".jpg" if desired.
It is made to display 20 images (5x4) on a screen and the monitor has to be 1900x1080 or larger. Once displayed, you can click on any picture and change its filename. It crashes at about 250 images (usually page 12 or so.) The freegadget stuff I commented out but it doesn't work anyway. And maybe I am wrong about it being a memory problem. That is my best guess. Here is the code:
include "dir.bi"
include once "window9.bi"
/'provides constants to use for the attrib_mask parameter
changes filename on disk 9/2020
Its working for jpgs
added free_gadget but it doesn't seem to do anything
'/
declare sub shell_sort()
declare sub free_gadget()
dim shared as integer sort1,sort2,sort3,sort4,sort5,sort6
declare sub list_files(ByRef filespec As String, ByVal attrib As Integer)
declare sub load_images()
Dim shared As integer hwnd,event,BS_PUSHLIKE,BS_AUTOCHECKBOX,ES_WANTRETURN
dim shared as integer total, attrib,indx,total_even
dim shared as string files(2500),fname,fend
dim shared as integer size_x,size_y
Dim shared As integer i,col,image_num,l,k,row
size_x=320:size_y=240
list_files "*"+fend, attrib
shell_sort()
load_images()
Do
event=WaitEvent()
If event=EventClose Then End
Select Case event
case EventGadget
select case EventNumber
case 1 to 20
l=len(files(EventNumber+indx20))
fname=left(files(EventNumber+indx20),l-4)
fname=InputBox("Change Filename","Enter New Name (no ending)",fname,ES_WANTRETURN)
Name(files(EventNumber+indx20),fname+fend)
files(EventNumber+indx20)=fname+fend
Sub list_files (ByRef filespec As String, ByVal attrib As Integer)
Dim As String filename = Dir(filespec, attrib)
Do While Len(filename) > 0
total=total+1
files(total)=filename
filename = Dir()
Loop
' print total
total_even=int((total+19)/20)*20
for i=total+1 to total_even
files(i)="zzz"
next
for i=1 to total_even
print files(i),
next
End Sub
'-------------------
sub load_images()
print indx,image_num
k=0:row=0:col=0
for col=0 to 3
for row=0 to 4
k=k+1
image_num=image_num+1
Var HIMAGE=Load_image(files(image_num))
HIMAGE=Resize_image( HIMAGE,size_x,size_y)
ButtonImageGadget(k,0+size_xrow,0+size_ycol,size_x,size_y,HIMAGE, BS_PUSHLIKE Or BS_AUTOCHECKBOX)
Free_Image(HIMAGE)
Lsort3:
sort6 = sort5 + sort2
IF files(sort5) <= files(sort6) THEN GOTO Lsort4 'item to be sorted
SWAP files(sort5), files(sort6) 'item to be sorted
sort5 = sort5 - sort2
IF sort5 < 1 THEN GOTO Lsort4
GOTO Lsort3
Lsort4:
sort3 = sort3 + 1
IF sort3 > sort4 THEN GOTO Lsort1
GOTO Lsort2
endit:
end sub
/'
sub free_gadget()
for i=1 to 20
'Free_Image(HIMAGE)
freegadget(i)
next
end sub
'/
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
4) in the load_images () procedure load images like this:
foriasLong=1to20dimimgFullSizeasHbitmapdimasLongimgWidth=320 , imgHeight=240ifimages(i)<>0thenFree_Image(images(i))' first we free the image in the array cellimgFullSize=Load_image(file)' load imageimages(i)=Resize_image(imgFullSize ,imgWidth , imgHeight)' cut and save the image to an array cellFree_Image(imgFullSize)' free memory full image setimagegadget(i , images(i))' display the image in ButtonImageGadget Next
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Stabud,
Thank you for your information. It has taken me a while to work through this, but I have it working now, and understand how it works more thoroughly. I really appreciate the help!
John
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Stabud,
I pretty much have it all working properly with your suggestions. thank you. I have one question. When I run this program, I get an error message in the terminal for each jpg loaded. I think I asked this question on the freebasic forums and did not get an answer that I was able to implement. Hopefully I didn't ask it of you before. I would hate to repeat myself. Here is the error message I get, and it doesn't seem to affect anything, but I would like to know how to get rid of it.
This shows up once for each file loaded. It appears that it is referring to the imgScaled rather than the imgFullSize
I do not understand the error message, nor do I know how to get rid of it. Any help or suggestions as to what it means would be appreciated.
Thanks,
John
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This code below:---------------------------------------------------------------------------------------------------
include "dir.bi"
include once "window9.bi"
Dim shared As integer hwnd
dim shared as string fend
dim shared as long size_x,size_y,index
dim shared imgFullSize as Hbitmap
dim shared imgScaled as Hbitmap
size_x=320:size_y=240
fend=".JPG"
index=0
hwnd=OpenWindow("Images",1700,200,800,600)
ButtonImageGadget(2,size_x,size_y,size_x,size_y,imgScaled)
free_image(imgFullSize)
free_image(imgScaled)
imgFullSize = Load_image("HUNT1030.JPG")' load image
Do
var ev=WaitEvent()
If ev=EventClose Then End
Loop
imgScaled=Resize_image(imgFullSize,size_x,size_y)setimagegadget(2,imgScaled)' display the image iGives the error twice:(error_test:7036): GLib-GObject-CRITICAL **: 07:32:05.818: g_object_unref: assertion 'G_IS_OBJECT(object)'failed
Do you call the FREE_IMAGE function and then use the image functions? The FREE_IMAGE function is called when the image is no longer needed. Basically: after calling FREE_IMAGE, the image no longer exists and any access to this image causes an error, even if it is displayed in the gadget.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
No , that was leftover from when I chopped unnecessary lines out to shorten the example. In my program I free up the image and then add a new one to the button. In the first example I get the error without freeing up anything.
I did run into this (Basically: after calling FREE_IMAGE, the image no longer exists and any access to this image causes an error, even if it is displayed in the gadget.) in my program. On the last page of my images if there were buttons that should have been blank, they displayed the old image from the page before, one that had been freed. I had to grab a blank image and then load the blank image to cover over the old image so that unused buttons were grey rather than displaying an old image from the page before.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Try checking what the BITMAP is before sending it to the RESIZE_IMAGE function:
Var bitmap=Load_image("image.jpg")
if bitmap then
messbox("success" , "success")
Resize_image(.....)
else
messbox("error" , "error")
endif
I can't find the error from here. Unambiguously, an invalid BITMAP is received in the RESIZE_IMAGE function or other functions. Find this place in the code where the error takes off. Most likely you made a mistake with the file load line in Load_image
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am writing a program that displays 20 (320x240)images in a window using 20 imagegadgets. I then try to replace those images with new ones, and I seem to crash after displaying 240 images. I think that is a memory problem. Is there a way to display an image on the button and then clear that memory and display a second image? I am doing that, but I think I am filling memory up and that causes the crash... I have been playing with freegadget and free_image, but it still crashes. Any help appreciated,
Thanks,
John
Hi John!
Provide code + images, then maybe we will find a solution or errors.
The object of the program is to look through hundreds or thousands of images 20 at a time, and when one finds an interesting one, to rename it.
I am using hundreds of images so they would be hard to provide. (output from a game(wild animal) camera that has been taking pictures for months. That being said, any jpgs larger than 320x240 in the directory should be sorted, loaded, shrunk to 320x240 and displayed. As the code is shown the last 4 characters in the file name have to be ".JPG" to be recognized. That can be changed by changing the fend variable to ".jpg" if desired.
It is made to display 20 images (5x4) on a screen and the monitor has to be 1900x1080 or larger. Once displayed, you can click on any picture and change its filename. It crashes at about 250 images (usually page 12 or so.) The freegadget stuff I commented out but it doesn't work anyway. And maybe I am wrong about it being a memory problem. That is my best guess. Here is the code:
include "dir.bi"
include once "window9.bi"
/'provides constants to use for the attrib_mask parameter
changes filename on disk 9/2020
Its working for jpgs
added free_gadget but it doesn't seem to do anything
'/
declare sub shell_sort()
declare sub free_gadget()
dim shared as integer sort1,sort2,sort3,sort4,sort5,sort6
declare sub list_files(ByRef filespec As String, ByVal attrib As Integer)
declare sub load_images()
Dim shared As integer hwnd,event,BS_PUSHLIKE,BS_AUTOCHECKBOX,ES_WANTRETURN
dim shared as integer total, attrib,indx,total_even
dim shared as string files(2500),fname,fend
dim shared as integer size_x,size_y
Dim shared As integer i,col,image_num,l,k,row
size_x=320:size_y=240
'----- start
fend=".JPG"
indx=0
hwnd=OpenWindow("Images",1700,200,1700,1020)
list_files "*"+fend, attrib
shell_sort()
load_images()
Do
event=WaitEvent()
If event=EventClose Then End
Select Case event
case EventGadget
select case EventNumber
case 1 to 20
l=len(files(EventNumber+indx20))
fname=left(files(EventNumber+indx20),l-4)
fname=InputBox("Change Filename","Enter New Name (no ending)",fname,ES_WANTRETURN)
Name(files(EventNumber+indx20),fname+fend)
files(EventNumber+indx20)=fname+fend
'indx=EventNumber
End Select
End Select
Loop
'----- end
Sub list_files (ByRef filespec As String, ByVal attrib As Integer)
Dim As String filename = Dir(filespec, attrib)
Do While Len(filename) > 0
total=total+1
files(total)=filename
filename = Dir()
Loop
' print total
total_even=int((total+19)/20)*20
for i=total+1 to total_even
files(i)="zzz"
next
for i=1 to total_even
print files(i),
next
End Sub
'-------------------
sub load_images()
print indx,image_num
k=0:row=0:col=0
for col=0 to 3
for row=0 to 4
k=k+1
image_num=image_num+1
Var HIMAGE=Load_image(files(image_num))
HIMAGE=Resize_image( HIMAGE,size_x,size_y)
ButtonImageGadget(k,0+size_xrow,0+size_ycol,size_x,size_y,HIMAGE, BS_PUSHLIKE Or BS_AUTOCHECKBOX)
Free_Image(HIMAGE)
next:next
buttongadget(21,1600,200,90,50,"Last 20")
buttongadget(22,1600,250,90,50,"Next 20")
TextGadget(23,1620,300,90,50,"page "+str(indx+1))
end sub
sub shell_sort()
sort1 = total_even 'number of items to be sorted
sort2 = sort1
Lsort1:
sort2 = INT(sort2 / 2)
IF sort2 = 0 THEN goto endit
sort3 = 1: sort4 = sort1 - sort2
Lsort2:
sort5 = sort3
Lsort3:
sort6 = sort5 + sort2
IF files(sort5) <= files(sort6) THEN GOTO Lsort4 'item to be sorted
SWAP files(sort5), files(sort6) 'item to be sorted
sort5 = sort5 - sort2
IF sort5 < 1 THEN GOTO Lsort4
GOTO Lsort3
Lsort4:
sort3 = sort3 + 1
IF sort3 > sort4 THEN GOTO Lsort1
GOTO Lsort2
endit:
end sub
/'
sub free_gadget()
for i=1 to 20
'Free_Image(HIMAGE)
freegadget(i)
next
end sub
'/
Your error seems to occur due to the fact that you do not free memory after resize_image.
The principle should be as follows:
Advice:
1) No need to create 20 gadgets every time (ButtonImageGadget). Use SetImageGadget to change the image in it.
2) Create an array for images at the beginning of the program, for example:
dim shared as Hbitmap images(1 to 20)
3) create gadgets (ButtonImageGadget) at the beginning of the program c ID from 1 to 20 :
4) in the load_images () procedure load images like this:
Hi Stabud,
Thank you for your information. It has taken me a while to work through this, but I have it working now, and understand how it works more thoroughly. I really appreciate the help!
John
Hi Stabud,
I pretty much have it all working properly with your suggestions. thank you. I have one question. When I run this program, I get an error message in the terminal for each jpg loaded. I think I asked this question on the freebasic forums and did not get an answer that I was able to implement. Hopefully I didn't ask it of you before. I would hate to repeat myself. Here is the error message I get, and it doesn't seem to affect anything, but I would like to know how to get rid of it.
(320x240-JPG_image_renamer2:15597): GLib-GObject-CRITICAL **: 18:34:19.314: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
HUNT1054.JPG
This shows up once for each file loaded. It appears that it is referring to the imgScaled rather than the imgFullSize
I do not understand the error message, nor do I know how to get rid of it. Any help or suggestions as to what it means would be appreciated.
Thanks,
John
Hi! I have no such mistakes. The most simple code attach where this error appears.
I can give you two examples. I think the first is from the window9 documentation.
Include "window9.bi"
Var hbitmap=Load_image("IMG_0001.JPG")
hbitmap=Resize_image( hbitmap,800,600)
OpenWindow("",1600,10,800,600)
ImageGadget(1,10,10,100,100,hbitmap)
'Free_Image(hbitmap)
'ImageGadget(2,110,10,800,600,hbitmap)
Do
var ev=WaitEvent()
If ev=EventClose Then End
Loop
The above gives this error:
(one_image:6978): GdkPixbuf-CRITICAL **: 07:31:01.778: gdk_pixbuf_scale_simple: assertion 'GDK_IS_PIXBUF (src)' failed
This code below:---------------------------------------------------------------------------------------------------
include "dir.bi"
include once "window9.bi"
Dim shared As integer hwnd
dim shared as string fend
dim shared as long size_x,size_y,index
dim shared imgFullSize as Hbitmap
dim shared imgScaled as Hbitmap
size_x=320:size_y=240
fend=".JPG"
index=0
hwnd=OpenWindow("Images",1700,200,800,600)
ButtonImageGadget(2,size_x,size_y,size_x,size_y,imgScaled)
free_image(imgFullSize)
free_image(imgScaled)
imgFullSize = Load_image("HUNT1030.JPG")' load image
Do
var ev=WaitEvent()
If ev=EventClose Then End
Loop
(error_test:7036): GLib-GObject-CRITICAL **: 07:32:05.818: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
In both cases the code runs ok.
John
Do you call the FREE_IMAGE function and then use the image functions? The FREE_IMAGE function is called when the image is no longer needed. Basically: after calling FREE_IMAGE, the image no longer exists and any access to this image causes an error, even if it is displayed in the gadget.
No , that was leftover from when I chopped unnecessary lines out to shorten the example. In my program I free up the image and then add a new one to the button. In the first example I get the error without freeing up anything.
I did run into this (Basically: after calling FREE_IMAGE, the image no longer exists and any access to this image causes an error, even if it is displayed in the gadget.) in my program. On the last page of my images if there were buttons that should have been blank, they displayed the old image from the page before, one that had been freed. I had to grab a blank image and then load the blank image to cover over the old image so that unused buttons were grey rather than displaying an old image from the page before.
Try checking what the BITMAP is before sending it to the RESIZE_IMAGE function:
Var bitmap=Load_image("image.jpg")
if bitmap then
messbox("success" , "success")
Resize_image(.....)
else
messbox("error" , "error")
endif
I can't find the error from here. Unambiguously, an invalid BITMAP is received in the RESIZE_IMAGE function or other functions. Find this place in the code where the error takes off. Most likely you made a mistake with the file load line in Load_image
This test code ran without an error shown in the terminal, and gave the success message. Thanks for your help. I will keep looking.
John