Changing color of an image...

Blitz3D Forums/Blitz3D Programming/Changing color of an image...

OrcSlayer(Posted 2004) [#1]
I was using the text command for my game crosshair (a + sigh worked well when I was too lazy to use an image). Now I have an image that I put on the screen with the DrawImage() command and it works just as expected, however I want to know if there is a way to change the color of the image through code. I like the way you can alter the color of text with the Color() command, and entities with the EntityColor() command. However, I don't see any similar commands for use with images. Am I missing something?


_PJ_(Posted 2004) [#2]
I am assuming you are writing perhaps a first-person shooter type game.

If you use a Sprite, parented to the camera (or a pivot-parented to the camera etc - so that it stays in view and moves with the camera) - if the sprite is a white crosshair on a black (so it's transparent) background - EntityColor will affect the colour of the sprite.

Otherwise, I don't know if WritePixelFast is any good? ( I haven't used that command really!)


Ross C(Posted 2004) [#3]
Well, since an image can be many differentpixel colours, there isn't really a command that can be used. You can use writepixelfast tho, to write new color info to the image.

BUT, if it's a cross hair, you could make that out of two rect's and it would use the current drawing color for that.

OR, You could load in an animated image, with mulitple frames. Each frame is the color of cross hair you want.

Hope some of that helps :)


Shambler(Posted 2004) [#4]
Sprite parented to the camera with EntityOrder -1 and coloured using EntityColor works fine for me.


OrcSlayer(Posted 2004) [#5]
True, this is for an FPS. I do use entitycolor a lot with sprites, for my particle effects and such, but I do not use sprites for HUD data. Currently I use the various 2D commands to create my overlay.

If it was absolutely required to have the different colors, I suppose I would use the sprite method. But, for now, I'll try WritePixel. If that isn't good enough, I'll just make a few fixed color crosshairs and live with it. Would be nice to give a UT style custom color though...

I wonder why there isn't a color command for images...you'd think it would be the same process that occurs to textures when you use entitycolor()...

Oh well, thanks for the suggestions. Perhaps once I figure out the writepixel function I can make a quasi-imagecolor function...


_PJ_(Posted 2004) [#6]

But, for now, I'll try WritePixel. If that isn't good enough, I'll just make a few fixed color crosshairs and live with it.


Good luck! I would recommend Ross C's advice then, and use a single bitmap with multiple frames


I wonder why there isn't a color command for images...you'd think it would be the same process that occurs to textures when you use entitycolor()...


I think it's due to the way 3D objects are rendered. Similar to how they become mipmapped/aliased and have light effects altering their apparent colour. An image is just an image and maybe is more required NOT to change color at all!


Ross C(Posted 2004) [#7]
I wouldn't mix 2D with 3D if i were you. Alot of computer have a hard time with it, something to do with different drawing instuctions, so i'd go for sprites instead of images. That way you change change the colours of things with entitycolor :)


Genexi2(Posted 2004) [#8]
Well, here's a function I made awhile ago that kinda does that , problem is, it USED to work when I last tried it...but now it doesnt....maybe you can take a look at it and fix it :

See fixed version of the code in my next post.



_PJ_(Posted 2004) [#9]
			If red <> MR And green <> MG And blue <> MB Then 
				WritePixelFast j,i, zz, ImageBuffer(image)


Where's red,green and blue defined? shoiuld they be R,G,B or something?


and do the Rect commands need a '1' at the end to fill them?
in fact...MR MG MB aren't returned....


Im at work at the mo and no access to B3D :(


Genexi2(Posted 2004) [#10]
Bah, that code was really messed up in the var's, so I did a partial rewrite, along with addin' a function to just change the color of the image.
(my function there actually made a new image and returned it, this one changes the image it was given to handle)

Graphics 640,480,0,2

Global img = CreateImage(128,128)

SetBuffer ImageBuffer(img)
Color 255,0,0
Rect 0,0,128,128,1
Color 0,255,255
Rect 32,32,64,64,1


; Make IMG2 by copyin' img and changin' its color
Global img2 = ImageColor(img,150,150,150,0,255,255)

; Now lets just change IMG2's color itself
ChangeColor(img2,255,255,0,255,0,0)


SetBuffer BackBuffer()
While Not KeyHit(1)
Cls

DrawImage img,0,0
DrawImage img2,128,0

Flip
Wend
End



; Function - basically uses a multiply effect to change the colors
; image = handle of the source image
; r\g\b = the rgb you want to multiply the image with
; mr\mg\mg = the rgb of the color you want to keep out of the effect


;--------------------------------------------------;
; Creates new image, changes color, and returns it ;
;--------------------------------------------------;
Function ImageColor(image,R,G,B,MR,MG,MB)

	ii = CopyImage(image)
	
	x = ImageWidth(ii)
	y = ImageHeight(ii)

	SetBuffer ImageBuffer(ii)
	
	For i = 0 To y
		For j = 0 To x

			GetColor j,i
			
			rr = ColorRed()
			gg = ColorGreen()
			bb = ColorBlue()  

			sR# = rr / 255.0
			sG# = gg / 255.0
			sB# = bb / 255.0
			
			fR# = R * sR
			fG# = G * sG
			fB# = B * sB

			If rr <> MR And gg<> MG And bb<> MB Then  
				Color fR, fG, fB
				Rect j,i,1,1
			EndIf
		Next
	Next
	 
	SetBuffer BackBuffer()
	Return ii
	
End Function



;---------------------------------------
; Changes the Color of the given image ;
;---------------------------------------
Function ChangeColor(image,R,G,B,MR,MG,MB)

	x = ImageWidth(image)
	y = ImageHeight(image)

	SetBuffer ImageBuffer(image)
	
	For i = 0 To y
		For j = 0 To x

			GetColor j,i
			
			rr = ColorRed()
			gg = ColorGreen()
			bb = ColorBlue()  

			sR# = rr / 255.0
			sG# = gg / 255.0
			sB# = bb / 255.0
			
			fR# = R * sR
			fG# = G * sG
			fB# = B * sB

			If rr <> MR And gg<> MG And bb<> MB Then  
				Color fR, fG, fB
				Rect j,i,1,1
			EndIf
		Next
	Next
	 
	SetBuffer BackBuffer()
End Function



OrcSlayer(Posted 2004) [#11]
Is that true that you shouldn't overlay 2D on 3D? It works fine for me so far, and is soooo much easier than using sprites. If I need to switch to sprites for all my drawing functions, I'm going to be VERY messed up. Especially for dynamic HUD elements...


Ross C(Posted 2004) [#12]
It is true. What are your computer specs?

Also, if you wish to change the screen resolution (again, think of less powerful computers :) ), The images will look alot smaller, and will be positioned wrongly on the screen, or may not even appear on the screen, if the screen resolution is put down.

On the other hand, sprites and all other 3d elements, keep their positions, regardless of the screen resolution.
I'm not saying that you should definetly change it, but if you wanna make this run on a wide variety of computers, which you should ;), then consider switching to sprites or quads for the HUD.

Also, sprites give you the ability to have transparency in your HUD and all sorts of cool effects :)


_PJ_(Posted 2004) [#13]
to be honest, I have done exactly the same thing for the crosshair in my FPS game (overlayed an image instead of sprite). It works fine on both my computers (specs in sig) - The resolution is changeable through the use of ScaleImage and GraphicsWidth()/GraphicsHeight commands - It is a lot easier and quicker, but I appreciate sprites should be the way to go.