1. Loading A Graphic Using CxImage From User Input

Hey Guys,

Sorry for the long title, but I am in trouble. In my program Frost, I need to have it so a user can load a graphic file if his/her own and then have it displayed in the window inside of a group box. I am using the cxImage library so that the users can have more than just .bmp, anyways, here is my code.

 
procedure Add_Hero_WalkGfx(integer self, integer event, sequence parm) 
	fName = getOpenFileName(EDWin,file,GraphicType) 
	 
	if length(fName) = 0 then 
		return 
	end if 
	 
	handle = open(fName,"rb") 
	 
	if handle = -1 then 
		fn = message_box("File Load Error", 
						"File Error", 
						MB_TASKMODAL) 
	end if 
	 
	while 1 do 
		data = gets(handle) 
		 
	if atom(data) then 
		exit 
	end if 
	 
	data = data[1..length(data)-1] 
	 
	buffer = buffer & data 
	end while 
	 
	close(handle) 
	 
	HeroWalk_Gfx = CXI_LoadImage(file, CXI_FORMAT_UNKNOWN,0) 
	 
	CXI_Resize(HeroWalk_Gfx,120,100,CXI_GOOD_RESIZE) 
end procedure 
setHandler(Hero_WalkGfx_Add,w32HClick,routine_id("Add_Hero_WalkGfx")) 

I have declared some of the varialbes outside of the procedure, so don't worry about the variables not being declared.

new topic     » topic index » view message » categorize

2. Re: Loading A Graphic Using CxImage From User Input

I have no idea how to display images using win32lib. But if you want to get the actual image data from an image loaded with the CxImage wrapper then what you're looking for is probably:

-- sequence CXI_GetDIB(atom image) 
--	Returns the sequence {bits, width, height, bpp}. 
new topic     » goto parent     » topic index » view message » categorize

3. Re: Loading A Graphic Using CxImage From User Input

mic_ said...

I have no idea how to display images using win32lib. But if you want to get the actual image data from an image loaded with the CxImage wrapper then what you're looking for is probably:

-- sequence CXI_GetDIB(atom image) 
--	Returns the sequence {bits, width, height, bpp}. 

Thanks for the help, but that still didn't work.

new topic     » goto parent     » topic index » view message » categorize

4. Re: Loading A Graphic Using CxImage From User Input

See my other post with a function I wrote for creating a DIB from a CxImage.

-Greg

new topic     » goto parent     » topic index » view message » categorize

5. Re: Loading A Graphic Using CxImage From User Input

ghaberek said...

See my other post with a function I wrote for creating a DIB from a CxImage.

-Greg

I looked at it, added your code into my code, and my code still runs, however it is not displaying it on the screen. How do I use the function effectivley?

new topic     » goto parent     » topic index » view message » categorize

6. Re: Loading A Graphic Using CxImage From User Input

Andy said...

I looked at it, added your code into my code, and my code still runs, however it is not displaying it on the screen. How do I use the function effectivley?

First, you have to get the DIB from CxImage with my function, like this:

image = CXI_LoadImage( filename, filetype, 0 )
yourDIB = createDIBFromCxImage( image ) 

Then, you can either copyBlt() the image to the window during a paint event, like this:

procedure Main_onPaint( integer pSelf, integer pEvent, sequence pParams )
 
    copyBlt( Main, 0, 0, yourDIB ) 
 
end procedure 
setHandler( Main, w32HPaint, routine_id("Main_onPaint") ) 

Or you can create a Bitmap control and set the DIB using setBitmap(), like this:

constant myBmp = create( Bitmap, "", Main, 10, 10, 100, 100, 0 )
setBitmap( myBmp, yourDIB ) 

Either should work, though I have only tested the onPaint method.

-Greg

new topic     » goto parent     » topic index » view message » categorize

7. Re: Loading A Graphic Using CxImage From User Input

ghaberek said...
Andy said...

I looked at it, added your code into my code, and my code still runs, however it is not displaying it on the screen. How do I use the function effectivley?

First, you have to get the DIB from CxImage with my function, like this:

image = CXI_LoadImage( filename, filetype, 0 )
yourDIB = createDIBFromCxImage( image ) 

Then, you can either copyBlt() the image to the window during a paint event, like this:

procedure Main_onPaint( integer pSelf, integer pEvent, sequence pParams )
 
    copyBlt( Main, 0, 0, yourDIB ) 
 
end procedure 
setHandler( Main, w32HPaint, routine_id("Main_onPaint") ) 

Or you can create a Bitmap control and set the DIB using setBitmap(), like this:

constant myBmp = create( Bitmap, "", Main, 10, 10, 100, 100, 0 )
setBitmap( myBmp, yourDIB ) 

Either should work, though I have only tested the onPaint method.

-Greg

Thanks, the code does work, but for some reason, when ever I try to load a "user" selected image, my program crashes on me. I am probably doing something wrong in my code.

new topic     » goto parent     » topic index » view message » categorize

8. Re: Loading A Graphic Using CxImage From User Input

Andy said...

Thanks, the code does work, but for some reason, when ever I try to load a "user" selected image, my program crashes on me. I am probably doing something wrong in my code.

Nothing should change, except that you'll be calling getOpenFileName() to obtain the image file from the user. If you could post the code that's crashing, I could take a look at it.

-Greg

new topic     » goto parent     » topic index » view message » categorize

9. Re: Loading A Graphic Using CxImage From User Input

ghaberek said...
Andy said...

Thanks, the code does work, but for some reason, when ever I try to load a "user" selected image, my program crashes on me. I am probably doing something wrong in my code.

Nothing should change, except that you'll be calling getOpenFileName() to obtain the image file from the user. If you could post the code that's crashing, I could take a look at it.

-Greg

	fName = getOpenFileName(EDWin,file,GraphicType) 
	 
	if length(fName) = 0 then 
		return 
	end if 
	 
	handle = open(fName,"rb") 
	 
	while 1 do 
		data = gets(handle) 
		 
	if atom(data) then 
		exit 
	end if 
	 
	buffer = buffer & data 
	end while 
	 
	close(handle) 
	 
	HeroWalk_Gfx = CXI_LoadImage(file,GraphicType,0) 
	 
	HeroWalk_Gfx = createDIBFromCXImage(HeroWalk_Gfx) 
	 
	copyBlt(EDWin,710,220,HeroWalk_Gfx) 
end procedure 
setHandler(Hero_WalkGfx_Add,w32HClick,routine_id("Add_Hero_WalkGfx")) 
setHandler(EDWin,w32HPaint,routine_id("Add_Hero_WalkGfx")) 

That is my code for the user selected image. However whenever I actually tried to click on the image to have it displayed on the window it crashes.

new topic     » goto parent     » topic index » view message » categorize

10. Re: Loading A Graphic Using CxImage From User Input

Doesn't seem like such a good idea to load the image every time there's a Paint event. Even if you free the previously loaded image before loading the new one, there's no point in re-loading it unless the filename has changed.

Also, what's the point of 'buffer'? You're reading the entire file into a sequence.. then what?

And shouldn't this:

HeroWalk_Gfx = CXI_LoadImage(file,GraphicType,0)  

really be this:

HeroWalk_Gfx = CXI_LoadImage(fName,GraphicType,0) 

..?

new topic     » goto parent     » topic index » view message » categorize

11. Re: Loading A Graphic Using CxImage From User Input

Andy, you need to separate your onClick handler from your onPaint handler. The only thing you should be doing during a paint event, is painting. You should never interact with the user during a paint event, as doing so will halt the event and possibly cause a repainting, resulting in an infinite loop.

The method should be:

  1. React to a click event and prompt the user to select a file
  2. Load the image and store it in a top-level variable
  3. Trigger a repaint with repaintWindow()
  4. Blit the image to the screen during the paint event

Mic, the CXI_LoadImage() routine works two ways: You can either feed it a filename or a buffer of a file in memory (in which case the third parameter should be the buffer size). The latter is useful for loading images from a database and such. But it seems Andy only needs to use the filename version, as his user is selecting a file via getOpenFileName().

-Greg

new topic     » goto parent     » topic index » view message » categorize

12. Re: Loading A Graphic Using CxImage From User Input

ghaberek said...

Mic, the CXI_LoadImage() routine works two ways

Ahem:

-- CxImage wrapper for Euphoria 
-- /Mic, 2003 

so.. yeah :P

ghaberek said...

You can either feed it a filename or a buffer of a file in memory (in which case the third parameter should be the buffer size). The latter is useful for loading images from a database and such. But it seems Andy only needs to use the filename version, as his user is selecting a file via getOpenFileName(). -Greg

Yeah the reason I asked was because he never used the data he read from the file, at least not in the posted code. But a bigger problem is probably that the wrong variable seems to be passed as the filename to CXI_LoadImage.

new topic     » goto parent     » topic index » view message » categorize

13. Re: Loading A Graphic Using CxImage From User Input

mic_ said...

Ahem:

-- CxImage wrapper for Euphoria 
-- /Mic, 2003 

so.. yeah tongue

LOL, nice... grin It's a wonder I never put that together. getlost

-Greg

new topic     » goto parent     » topic index » view message » categorize

14. Re: Loading A Graphic Using CxImage From User Input

mic_ said...
ghaberek said...

Mic, the CXI_LoadImage() routine works two ways

Ahem:

-- CxImage wrapper for Euphoria 
-- /Mic, 2003 

so.. yeah :P

ghaberek said...

You can either feed it a filename or a buffer of a file in memory (in which case the third parameter should be the buffer size). The latter is useful for loading images from a database and such. But it seems Andy only needs to use the filename version, as his user is selecting a file via getOpenFileName(). -Greg

Yeah the reason I asked was because he never used the data he read from the file, at least not in the posted code. But a bigger problem is probably that the wrong variable seems to be passed as the filename to CXI_LoadImage.

I made some changes to the code, but it is still crashing. Here's the code

procedure Add_Hero_WalkGfx(integer self, integer event, sequence parm) 
	fName = getOpenFileName(EDWin,file,GraphicType) 
	 
	if length(fName) = 0 then 
		return 
	end if 
	 
	HeroWalk_Gfx = CXI_LoadImage(fName,GraphicType,0) 
	 
	HeroWalk_Gfx = createDIBFromCXImage(HeroWalk_Gfx) 
	 
	copyBlt(EDWin,710,220,HeroWalk_Gfx) 
end procedure 
setHandler(Hero_WalkGfx_Add,w32HClick,routine_id("Add_Hero_WalkGfx")) 

What am I doing wrong?

new topic     » goto parent     » topic index » view message » categorize

15. Re: Loading A Graphic Using CxImage From User Input

Do you know the exact place where it crashes? If you're not getting anything meaningful in ex.err, then at least try to find the function call that causes the crash (by commenting out calls until it no longer crashes).

new topic     » goto parent     » topic index » view message » categorize

16. Re: Loading A Graphic Using CxImage From User Input

mic_ said...

Do you know the exact place where it crashes? If you're not getting anything meaningful in ex.err, then at least try to find the function call that causes the crash (by commenting out calls until it no longer crashes).

I think its because I am calling the onPaint event incorrectley. How would I go about setting up the onPaint event correctley?

new topic     » goto parent     » topic index » view message » categorize

17. Re: Loading A Graphic Using CxImage From User Input

Andy said...

I made some changes to the code, but it is still crashing. Here's the code

(see below)

What am I doing wrong?

atom HeroWalk_Gfx
HeroWalk_Gfx = 0 
 
procedure Add_Hero_WalkGfx(integer self, integer event, sequence parm) 
	fName = getOpenFileName(EDWin,file,GraphicType) 
	 
	if length(fName) = 0 then 
		return 
	end if 
	 
	HeroWalk_Gfx = CXI_LoadImage(fName,GraphicType,0) 
	 
	HeroWalk_Gfx = createDIBFromCXImage(HeroWalk_Gfx) 
	 
	repaintWindow( Main ) 
 
end procedure 
setHandler(Hero_WalkGfx_Add,w32HClick,routine_id("Add_Hero_WalkGfx")) 
 
procedure EDWin_onPaint(integer self, integer event, sequence parm) 
 
	if HeroWalk_Gfx != 0 then 
		copyBlt(EDWin,710,220,HeroWalk_Gfx)  
	end if 
 
end procedure 
setHandler(EDWin,w32HPaint,routine_id("EDWin_onPaint")) 

-Greg

new topic     » goto parent     » topic index » view message » categorize

18. Re: Loading A Graphic Using CxImage From User Input

ghaberek said...
Andy said...

I made some changes to the code, but it is still crashing. Here's the code

(see below)

What am I doing wrong?

atom HeroWalk_Gfx
HeroWalk_Gfx = 0 
 
procedure Add_Hero_WalkGfx(integer self, integer event, sequence parm) 
	fName = getOpenFileName(EDWin,file,GraphicType) 
	 
	if length(fName) = 0 then 
		return 
	end if 
	 
	HeroWalk_Gfx = CXI_LoadImage(fName,GraphicType,0) 
	 
	HeroWalk_Gfx = createDIBFromCXImage(HeroWalk_Gfx) 
	 
	repaintWindow( Main ) 
 
end procedure 
setHandler(Hero_WalkGfx_Add,w32HClick,routine_id("Add_Hero_WalkGfx")) 
 
procedure EDWin_onPaint(integer self, integer event, sequence parm) 
 
	if HeroWalk_Gfx != 0 then 
		copyBlt(EDWin,710,220,HeroWalk_Gfx)  
	end if 
 
end procedure 
setHandler(EDWin,w32HPaint,routine_id("EDWin_onPaint")) 

-Greg

Ah, I used your code, but it still crahses. However the error says that there is a type_check failure. image type is {71,114,97,112...}

I am using a supported image type, so what is up?

new topic     » goto parent     » topic index » view message » categorize

19. Re: Loading A Graphic Using CxImage From User Input

Andy said...

Ah, I used your code, but it still crahses. However the error says that there is a type_check failure. image type is {71,114,97,112...}

I am using a supported image type, so what is up?

Your GraphicType value needs to be one of these constants, from CxImage.ew:

-- Image types. Used with CXI_LoadImage and CXI_SaveImage.
global constant CXI_FORMAT_UNKNOWN = 0, 
        CXI_FORMAT_BMP = 1, 
        CXI_FORMAT_GIF = 2, 
        CXI_FORMAT_JPG = 3, 
        CXI_FORMAT_PNG = 4, 
        CXI_FORMAT_ICO = 5, 
        CXI_FORMAT_TGA = 6, 
        CXI_FORMAT_PCX = 7 

I suspect you're passing it a sequence of "Grap..." something. (At least that's what your error message seems to indicate.)

-Greg

new topic     » goto parent     » topic index » view message » categorize

20. Re: Loading A Graphic Using CxImage From User Input

ghaberek said...
Andy said...

Ah, I used your code, but it still crahses. However the error says that there is a type_check failure. image type is {71,114,97,112...}

I am using a supported image type, so what is up?

Your GraphicType value needs to be one of these constants, from CxImage.ew:

-- Image types. Used with CXI_LoadImage and CXI_SaveImage.
global constant CXI_FORMAT_UNKNOWN = 0, 
        CXI_FORMAT_BMP = 1, 
        CXI_FORMAT_GIF = 2, 
        CXI_FORMAT_JPG = 3, 
        CXI_FORMAT_PNG = 4, 
        CXI_FORMAT_ICO = 5, 
        CXI_FORMAT_TGA = 6, 
        CXI_FORMAT_PCX = 7 

I suspect you're passing it a sequence of "Grap..." something. (At least that's what your error message seems to indicate.)

-Greg

Thanks, it appears to be working now, however, the image is displayed as a grey box, and it paints over the other controls. I have tried repaintRect, but it still shows the grey box. Here is the new code

 
procedure Add_Hero_WalkGfx(integer self, integer event, sequence parm) 
	fName = getOpenFileName(EDWin,file,GraphicType) 
	 
	if length(fName) = 0 then 
		return 
	end if 
	 
	HeroWalk_Gfx = CXI_LoadImage(fName,CXI_FORMAT_UNKNOWN,0) 
	 
	HeroWalk_Gfx = createDIBFromCXImage(HeroWalk_Gfx) 
	 
	repaintRect(EDWin,750,220,64,64) 
end procedure 
setHandler(Hero_WalkGfx_Add,w32HClick,routine_id("Add_Hero_WalkGfx")) 
 
procedure EDWin_onPaint(integer self, integer event, sequence parm) 
	if HeroWalk_Gfx != 0 then 
		copyBlt(EDWin,750,220,HeroWalk_Gfx) 
	end if 
end procedure 
setHandler(EDWin,w32HPaint,routine_id("EDWin_onPaint")) 
new topic     » goto parent     » topic index » view message » categorize

21. Re: Loading A Graphic Using CxImage From User Input

Rather than repainting the image on just part of your window, create a small child window the size of the image you want to display. That small window will receive its own paint events and will "clip" properly.

include Win32Lib.ew
without warning 
 
constant Main   = create( Window, "Test", 0, Default, Default, 640, 480, 0 ) 
constant PicWin = create( Window, "", Main, 10, 10, 64, 64, {WS_CHILD,WS_VISIBLE} ) 
 
procedure PicWin_onPaint( integer pSelf, integer pEvent, sequence pParams ) 
 
    copyBlt( PicWin, 0, 0, YourImage ) 
 
end procedure 
setHandler( PicWin, w32HPaint, routine_id("PicWin_onPaint") ) 
 
WinMain( Main, Normal )

Also, you may need to use transBlt() instead of copyBlt() if you need to preserve the transparent background of your image.

-Greg

new topic     » goto parent     » topic index » view message » categorize

22. Re: Loading A Graphic Using CxImage From User Input

ghaberek said...

Rather than repainting the image on just part of your window, create a small child window the size of the image you want to display. That small window will receive its own paint events and will "clip" properly.

include Win32Lib.ew
without warning 
 
constant Main   = create( Window, "Test", 0, Default, Default, 640, 480, 0 ) 
constant PicWin = create( Window, "", Main, 10, 10, 64, 64, {WS_CHILD,WS_VISIBLE} ) 
 
procedure PicWin_onPaint( integer pSelf, integer pEvent, sequence pParams ) 
 
    copyBlt( PicWin, 0, 0, YourImage ) 
 
end procedure 
setHandler( PicWin, w32HPaint, routine_id("PicWin_onPaint") ) 
 
WinMain( Main, Normal )

Also, you may need to use transBlt() instead of copyBlt() if you need to preserve the transparent background of your image.

-Greg

Thank you, it finally works. I'll make sure to acknowledge all those that helped in my software. Thank you all again.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu