WritePixels with transparent pixels

Monkey Forums/Monkey Programming/WritePixels with transparent pixels

Pierrou(Posted 2014) [#1]
Hi,

Here's what I would like to be able to do in my game : loading a few black and white images and colouring them using SetColor some time before displaying the whole next "level" (which would fit on a single screen and only feature a few sprites at a time). It's not a problem if reading and writing pixels takes some time.

I intend to use ReadPixels/WritePixels : I would
create an empty image using CreateImage,
then delete the screen (Cls something),
then SetColor to red,green,blue (SetColor 255,0,0 for a red item),
then display the B&W image,
then read the the coloured image's pixels from the screen
and at last write those pixels inside the newly created image.

Two questions :

1/ Do I really have to colour and display the black & white items inside OnRender() or can I do it from anywhere else?

2/ Is there a [simple?] way to avoid grabbing unwanted background colour pixels (black pixels when using Cls 0,0,0)? BlitzMax allowed to use some Mask Colour to achieve this and I suspect we could do the same by accessing each pixel's RGB value but I don't know how to do that.

Thanks in advance if you have any idea,


therevills(Posted 2014) [#2]
For 2, you can use this function:
Function MaskPixels:Void(pixels:Int[], maskRed:Int = 0, maskGreen:Int = 0, maskBlue:Int = 0)
	For Local i:Int = 0 Until pixels.Length
		Local argb:Int = pixels[i]
		Local a:Int = ( argb Shr 24 ) & $ff
		Local r:Int = ( argb Shr 16 ) & $ff
		Local g:Int = ( argb Shr 8 )  & $ff
		Local b:Int = argb & $ff
		If r = maskRed And g = maskGreen And b = maskBlue
			a = 0
			argb = (a Shl 24) | (r Shl 16) | (g Shl 8) | b
			pixels[i] = argb
		End
	Next
End



Pierrou(Posted 2014) [#3]
Thank you Therevills for that nice piece of code! The more I think of it, the more I think I'll keep it all simple and just use several image files (or image atlases) with different colours. The pngs I'm currently using are 5-10 ko each, I guess the app shouldn't get too big even if I use 10 different colors (even though the app could be 10 times smaller if I used Writepixels...)

At the moment I can't see how to avoid graphical artifacts like these white borders, because the images are blended with the background



(White 254,254,254 being the Masking Colour
I'm first deleting the screen using Cls 254,254,254, then colouring and displaying the pictures on that whiteish background, then reading pixels, then using Therevills' function to set the whiteish pixels' alpha to zero, then writing a new image and displaying it over a yellow background)


consty(Posted 2014) [#4]
If you want to change the colors of an image (e.g. of a player) it will be easier to switch the color palette rather than paint it from scratch.

I mean that if you want to do this way you though of "of having some black pixels that you would paint them" it will be better for monochromatic artwork, if you want to have more color tones in your images it will be a hell to manage all of this information.

My approach to this problem is that your image (e.g. a hero character) will be composed of two actual images, one image will hold the colors that need to change and one image will hold the colors that don't need to change. When you will want to draw the image you would simply call the DrawImage twice accordingly. Additionally, you could generate a new virtual image with these information for for optimization purposes, but chances are that you won't need to, unless is extremely important.

In this example I have uploaded you can see how it would look like.
http://postimg.org/image/40llaymgd/


The way to switch colors perhaps might be something to wrap values from 0 to 255 in circular, I have not tried it yet.

__________

Now regarding the graphical artifacts in the edges, are they occur from the programming language or the image format?


Pierrou(Posted 2014) [#5]
Thanks Consty. I'm about to try a mix of both ideas : instead of just one, I'll use two black & white pngs, one featuring the image's edges and one featuring the image's background. I'll only colour and read/write the background image's pixels. This way I can save some space and my characters will be able to wear randomly coloured clothes.




consty(Posted 2014) [#6]
Awesome work.


Pierrou(Posted 2014) [#7]
Thanks! I'm trying to keep everything simple, following the 50's "modern" cartoon style. Drawing characters using InkScape is probably going to be the funniest part of it all.

Codewise, the ReadPixels/WritePixels thing with two layers works well on simple examples but it would need quite some more work to be added to my actual Ignition X code. Probably too much extra work for me. Since I'm mainly targetting desktop and Android, I think I'll forget about HTML5 for now and just massively use SetColor to tint the characters' clothes, skin and hair. It's simple, quick and should work well.

Thanks again for helping!