saving image trouble

Blitz3D Forums/Blitz3D Beginners Area/saving image trouble

chwaga(Posted 2007) [#1]
Can someone tell me why the saving part of this doesnt work?
(there's a lot of fluff code in there, sorry!)
Graphics 1280, 1024, 32, 1
Global imageid, image, bias
Global r, g, b, av, n, m, bw, save, savename
SetBuffer FrontBuffer()


imageid=Input$("Image name and extension : ")
bias=Input$("To what nearest number should the rgb's be rounded to? ")
bw=Input$("Should the output image be black and white? (y/n) ")

;bias = Float bias 
;bias = bias/(bias*10)
If bias=0 Then bias=10
 
image=LoadImage ("image.jpg")

Cls

save=CreateImage(ImageWidth(image), ImageHeight(image))

DrawImage image, 0, 0
DrawImage image, 0, ImageHeight(image)

WaitKey()

For n=0 To ImageWidth (image)
For m=0 To ImageHeight (image)
GetColor n, m

r=ColorRed()
g=ColorGreen()
b=ColorRed()

If bw="y" Then 

r=(round( r, bias))
g=(round( g, bias))
b=(round( b, bias))
av = (r + g + b) / 3

r = av : g = av : b = av

Else

r=(round( r, bias))
g=(round( g, bias))
b=(round( b, bias))

EndIf 


Color r, g, b
;Plot 1280, 0
Rect 1000, 1000, 2, 2, 1

If ImageHeight(image) < 500 Then


WritePixelFast n, m + ImageHeight (image), ReadPixelFast(1000, 1000)


Else


WritePixel n, m + ImageHeight (image) , ReadPixel(1000, 1000)
 

EndIf 

DrawImage save, 0, ImageHeight(image)
If KeyHit(1) Then Goto endl


Next
Next 

CopyRect 0, ImageHeight(image), ImageWidth(image), ImageHeight(image), 0, 0, ImageBuffer(save)
DrawImage save, 0, 0

Repeat

Color 0, 0, 0
Rect 1000, 1000, 280, 24, 1
GetColor MouseX(), MouseY()
Text 1000, 1000, "mouse location rgb = " + ColorRed() + " " + ColorGreen() + " " + ColorBlue()
Text 1000, 900, "Hit spacebar to save the new image, escape to quit"

If KeyHit( 57 ) Then 
Locate 900, 980
savename=Input$("New image filename? (will save as bitmap) ") 
SaveImage (save, savename+".bmp")
EndIf 

Delay 15
Until KeyHit(1)
.endl
End




Function Round( Number , N )

   If ( Number Mod N ) >= ( N *.5 )
        Number  = ( Ceil( Number / N ) + 1 ) * N
   Else
        Number = Floor( Number / N ) * N
   EndIf

   Return Number

End Function

Function writepixelsfast()

If ImageHeight(image)*2 > 1024 Then
WritePixelFast n+ImageWidth(image), m, ReadPixelFast(1000, 1000)
Else If ImageWidth*2 > 1280 Then 
WritePixelFast n, m+ImageHeight (image), ReadPixelFast(1000, 1000)
EndIf 

End Function 

Function writepixels()

If ImageHeight(image)*2 > 1024 Then
WritePixel n+ImageWidth(image), m, ReadPixel(1000, 1000)
Else If ImageWidth*2 > 1280 Then 
WritePixel n, m+ImageHeight (image), ReadPixel(1000, 1000)
EndIf 

End Function 



Adam Novagen(Posted 2007) [#2]
That depends on what you mean by "doesn't work." Is it just failing to save the image, or are you getting a Runtime Error message? And if so, what does it say?


chwaga(Posted 2007) [#3]
you could have run the code yourself :).

It will save the image, but the saved image will have the correct resolution, but the image will be all black.


Floyd(Posted 2007) [#4]
you could have run the code yourself :).

Nearly everyone who reads your question and looks at the code will give up immediately. They have to supply an image and enter a rounding value with no idea of what it supposed to be. You should at least tell us what you did and what result you got.

...the saved image will have the correct resolution, but the image will be all black.

This suggests that the image saved correctly and really is all black. That's the first thing to check.


chwaga(Posted 2007) [#5]
I'm using copyrect to take the output pixels and put them into point 0, 0 in the image buffer of the image that is saved, these pixels are NOT black. When I copyrect the output pixels the same method onto 0, 0 of the frontbuffer, it shows the correct output image, but for some reason copying them into the imagebuffer and saving the image, will make the image all black.


JBR(Posted 2007) [#6]
Should you not be using global variables as you refer to them in functions? I'm not sure.

Jim


chwaga(Posted 2007) [#7]
erm...If i understand you correctly, you are deeply mistaken. Global variables are NEEDED in order to reach into functions.


JBR(Posted 2007) [#8]
Sorry bad expression. I'm saying you need to define a variable as Global if you are refering to it in a function.

i.e. Global image = ....

Jim


chwaga(Posted 2007) [#9]
I did, didn't I?


JBR(Posted 2007) [#10]
nope


chwaga(Posted 2007) [#11]
every single variable used in the code is a global...


Stevie G(Posted 2007) [#12]
.


JBR(Posted 2007) [#13]
Sorry chwaga I missed your declaration at the start.
Jim


Stevie G(Posted 2007) [#14]
It maybe something to do with the fact that your ROUND function uses N which is already declared as global.

Also, I've no clue what all this readpixel( 1000,1000 ) etc.. is for?


chwaga(Posted 2007) [#15]
when replacing N with "nu" in the function, it still doesnt work. (readpixel 1000, 1000 is reading the pixels of a rectangle used to view the current drawing color, I didn't want to mess with hex's)


big10p(Posted 2007) [#16]
The N in the function eclipses the global n, whilst in the function. However, using such short, non-descript names for globals is a bad idea. ;)

Also, Read/WritePixelFast should only be used on locked buffers, and specify the buffer in the call to them, too (I know it's supposed to be an optional param, but I can never get them to work unless I specify the buffer being used).

Make sure you're not writing pixels outside of the buffers area, too.


Stevie G(Posted 2007) [#17]
To be frank your code is a bit of a mess. If you don't want to use hex's then readpixelfast and writepixel fast are useless to you and it'd be slow as hell.

Here ...

Graphics 1280, 1024, 32, 1

Global IMAGEin = CreateImage( 256,256 )		;LoadImage( "MyImage.bmp" )

;make a test image
SetBuffer ImageBuffer( IMAGEin )
For x = 0 To 255
	For y= 0 To 255
		Color Rand(0,255), Rand(0,255), Rand(0,255)
		Plot x,y
	Next
Next
SetBuffer BackBuffer()


Global IMAGEout = IMAGEprocess( IMAGEin , 10 ,  True )
Cls
DrawImage IMAGEin, 0,0
DrawImage IMAGEout, 600,0
Flip

WaitKey()
End

;===========================================================================
;===========================================================================
;===========================================================================

Function IMAGEprocess( IMAGEin , Bias=10, BW=False ) 

	IW = ImageWidth( IMAGEin )
	IH = ImageHeight( IMAGEin )
	IMAGEout = CreateImage( IW , IH )

	LockBuffer ImageBuffer( IMAGEin )
	LockBuffer ImageBuffer( IMAGEout )

	For y = 0 To IH-1
		For x = 0 To IW-1
			ARGB = ReadPixelFast( x, y , ImageBuffer( IMAGEin ) )

			A = ( ARGB And $FF000000 ) Shr 24
			R = ( ARGB And $FF0000 ) Shr 16
			G = ( ARGB And $FF00 ) Shr 8
			B = ( ARGB And $FF )

			R = ROUND( R , Bias )
			G = ROUND( G , Bias )
			B = ROUND( B , Bias )
			
			If BW
				AV = ( R + G + B ) / 3
				R = AV
				G = AV
				B = AV
			EndIf	

			ARGB = ( A Shl 24 ) Or ( R Shl 16 ) Or ( G Shl 8 ) Or B
			
			WritePixelFast x, y, ARGB, ImageBuffer( IMAGEout )

		Next
	Next
	UnlockBuffer ImageBuffer( IMAGEin )
	UnlockBuffer ImageBuffer( IMAGEout )
	
	Return IMAGEout
	
End Function

;===========================================================================
;===========================================================================
;===========================================================================

Function Round( Number , N )

   If ( Number Mod N ) >= ( N *.5 )
        Number  = ( Ceil( Number / N ) + 1 ) * N
   Else
        Number = Floor( Number / N ) * N
   EndIf

   Return Number

End Function



You may have to limit the R , G , B values so that they don't exceed 255.

Stevie


JBR(Posted 2007) [#18]
Stevie you have beaten me to it but I'll post anyway....


Graphics 1280, 1024, 32, 1

Global imageid$ =Input$("Image name and extension : ")
Global bias$    =Input$("To what nearest number should the rgb's be rounded to? ")
Global bw$      =Input$("Should the output image be black and white? (y/n) ")

Global image=LoadImage ("StarComm.jpg")

Global save=CreateImage(ImageWidth(image), ImageHeight(image))


LockBuffer ImageBuffer(image)
LockBuffer ImageBuffer(save)
;--------------------------------------------------------------------------
For y=0 To ImageHeight (image) - 1
	For x=0 To ImageWidth (image) - 1
	
		pix% = ReadPixelFast( x,y, ImageBuffer(image) )

		r=(pix% Shr 16) And 255
		g=(pix% Shr  8) And 255
		b=(pix% Shr  0) And 255

		If bw$="y" Then 

			r=(round( r, bias))
			g=(round( g, bias))
			b=(round( b, bias))
			av = (r + g + b) / 3

			r = av : g = av : b = av

		Else

			r=(round( r, bias))
			g=(round( g, bias))
			b=(round( b, bias))

		EndIf 

		pix% = (r Shl 16) + (g Shl 8) + b

		WritePixelFast x, y, pix%, ImageBuffer(save)
 
	Next
Next 
;---------------------------------------------------------------------------
UnlockBuffer ImageBuffer(image)
UnlockBuffer ImageBuffer(save)

savename$=Input$("New image filename? (will save as bitmap) ") 
SaveImage (save, savename$+".bmp")
End

Function Round( Number , N )

   If ( Number Mod N ) >= ( N *.5 )
        Number  = ( Ceil( Number / N ) + 1 ) * N
   Else
        Number = Floor( Number / N ) * N
   EndIf

   Return Number

End Function


Jim


chwaga(Posted 2007) [#19]
thanks guys!! (I realize my code was crap, wasn't really thinking when i was doing it, thanks!)

Here's Jim's code with a few revisions (the bw code was in the wrong order and done incorrectly fixed that), thanks for all the help guys!

Graphics 1280, 1024, 32, 1
.redo
Locate 0, 0
Cls 
Global imageid$ =Input$("Image name and extension (default extension is jpeg) : ")
If imageid$ = "" Then Goto redo


Global bias$    =Input$("To what nearest number should the rgb's be rounded to? ")
Global bw$      =Input$("Should the output image be black and white? (y/n) ")
If bias=256 Then bias=255

If Instr (imageid$, ".", 1) Then
Else
imageid$=imageid$+".jpg"
EndIf 

Global image=LoadImage ("" + imageid$)

Global save=CreateImage(ImageWidth(image), ImageHeight(image))

DrawImage image, 0, 0
Locate 700, 1000
LockBuffer ImageBuffer(image)
LockBuffer ImageBuffer(save)
;--------------------------------------------------------------------------
For y=0 To ImageHeight (image) - 1
	For x=0 To ImageWidth (image) - 1
	
		pix% = ReadPixelFast( x,y, ImageBuffer(image) )

		r=(pix% Shr 16) And 255
		g=(pix% Shr  8) And 255
		b=(pix% Shr  0) And 255

		If bw$="y" Then 


			av = (r + g + b) / 3
			
			r=(round( av, bias))
			g=(round( av, bias))
			b=(round( av, bias))

		Else

			r=(round( r, bias))
			g=(round( g, bias))
			b=(round( b, bias))

		EndIf 
		
		

		pix% = (r Shl 16) + (g Shl 8) + b

		WritePixelFast x, y, pix%, ImageBuffer(save)
 
	Next
Next 
;---------------------------------------------------------------------------
UnlockBuffer ImageBuffer(image)
UnlockBuffer ImageBuffer(save)
If ImageHeight(image)*2 > GraphicsHeight() Then 
DrawImage save,  ImageWidth(image), 0
Else
DrawImage save, 0, ImageHeight(image), 0
EndIf 

savename$=Input$("New image filename? (will save as bitmap, supply no name to not save) ") 

If savename$="" Then 
Else
SaveImage (save, savename$+".bmp")
EndIf
FlushKeys()
Repeat 

Text 800,  980, "Press Escape to Exit, Space to reset."
If KeyHit(57) Then Goto redo

Until KeyHit(1)
End

Function Round( Number , N )

   If ( Number Mod N ) >= ( N *.5 )
        Number  = ( Ceil( Number / N ) + 1 ) * N
   Else
        Number = Floor( Number / N ) * N
   EndIf

   Return Number

End Function


...so, from what I'm reading in the code, using
		r=(pix% Shr 16) And 255
		g=(pix% Shr  8) And 255
		b=(pix% Shr  0) And 255
and
		pix% = (r Shl 16) + (g Shl 8) + b
makes it hex?


JBR(Posted 2007) [#20]
http://en.wikipedia.org/wiki/Hexadecimal

check out binary aswell.
Jim