How do I get a colored texture brush to show up in Open GL ES on white background? - iphone

I want to draw with a texture brush, in a color of my choice, on a white background using OpenGLES.
I have a bitmap image which I use CG to load and turn into a texture. This bitmap is mostly black, but has a white circle in the center that I want to use as the "brush". In other words, I want the black part to vanish in the final compositing, but the white part to take on the color that I set using glColor.
The best I can get is with the blend parameters (GL_SRC_ALPHA, GL_ONE) after setting some opaque bright color is a faded color line on a grey (not pure white background). But when I set the background to pure white, the line isn't visible.
At least in the current situation, the black edges of the original texture don't appear. Most other blend combinations I'm trying cause either nothing to show up even on grey, or to see the entire brush including the black edges, which is no good.
Is anyone willing to explain to me how I should set up my texture and/or GL states to make the bright color show through on pure white, without showing the black texture edges at all? This might be a newbie question, but I've tried working through the blend math, and I still just don't understand how the colors are all being factored together.
Here's the image I'm using as the brush:
alt text http://www.coldcoffeeandjuice.com/OpaqueBrush.png
Here's some resulting output, when the background is grey, and the glColor4f is set to (1, 0, 0, 1), eg pure red, and the brush is used on a bunch of consecutive GL_POINTs. Note that what's good about this is that only the white part of the brush image shows the color red-- that's right. The bad parts is that the red which I want to be pure and bright is pale due to being blended with the background (?) and/or the white of the brush (?) so that it washes out entirely if the background is pure white. This uses the blend params as given above (src_alpha, one).
(source: coldcoffeeandjuice.com)
Here's what I want to see, given the pure red color (thanks Paintbrush):
(source: coldcoffeeandjuice.com)
Can anyone help me understand what I'm doing wrong?
Thanks!

Ok, so you're trying to "paint" a given colour (in this case "red") on to a background, using a mask for the brush shape.
You need to do the following before you start rendering the "paint":
First make sure your brush has an alpha channel that corresponds with its shape - that is the alpha channel should look similar to the brush image you posed.
Render with these states set (note space to get around wiki markup):
// Make the current material colour track the current color
glEnable( GL_COLOR_MATERIAL );
// Multiply the texture colour by the material colour.
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// Alpha blend each "dab" of paint onto background
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
See also:
http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/colormaterial.html
http://www.khronos.org/opengles/documentation/opengles1_0/html/glTexEnv.html

Related

CGContext draw with two UIColor with opacity

I am drawing a line using CGContext and color has transparency of 0.7 , Now i want to draw another line with another color with same transparency on that previous line . But i get the second line color as a solid color without any transparency in the part where this both two lines intersect. For first line i am using blend effect clear to draw a transparent line and for the second line i am using blend effect color. Please tell me how to draw these two lines separately so that the second line drawn can have its own separate color .
The default blending mode (kCGBlendModeNormal) should provide the behavior you want in both cases.

iPhone iOS how to instantiate a black and white CGColorSpaceRef?

I'm working with this excellent example of converting an image to grayscale: Convert Image to B&W problem CGContext - iPhone Dev
However, for my purposes, I would like to have only pure black and pure white left in the image.
It appears that to do so, I need to pass a black and white color space to the recolor method using a call:
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(/*black and white name*/);
However, I was unable to find the proper iOS color space names. What I found was from Mac, and the "color space names" referenced from the iOS docs does not point anywhere.
How can I properly create a black and white CGColorSpaceRef?
Thank you!
I am not familiar with a black and white only color space but what you can do is calculate the total average RGB value from all the pixels (lets call it totalAvg) and use it as a threshold. Meaning for each pixel if its rgb average is greater than the calculated totalAvg than set it to pure white, otherwise set it to pure black.
I agree it is a bit of more work but thats whay I can think of unless you find the colorspace you are looking for.
You might try creating a gray color space, then creating an indexed color space with two colors (black and white, obviously) and using that.

Only White Fill Color is Transparent in UIView

I've got a UIView that is set to opaque = NO and it all works nicely. In the drawRect I'm doing custom drawing, and this works
CGContextSetFillColor(context, CGColorGetComponents([UIColor blueColor].CGColor));
CGContextFillRect(context, labelOutside);
CGContextAddRect(context, labelOutside);
but this
CGContextSetFillColor(context, CGColorGetComponents([UIColor whiteColor].CGColor));
CGContextFillRect(context, labelOutside);
CGContextAddRect(context, labelOutside);
results in NO fill being produced (you can even see other stuff that I drew on the CGContext through it). How can I draw a white fill?
Note: If I set the control not be opaque, it still doesn't work.
Why not use CGContextSetFillColorWithColor? Then you can pass the CGColor object directly instead of extracting its components and assuming it's in the same color space as the context.
Edited to add:
this works
CGContextSetFillColor(context, CGColorGetComponents([UIColor blueColor].CGColor));
but this
CGContextSetFillColor(context, CGColorGetComponents([UIColor whiteColor].CGColor));
results in NO fill being produced (you can even see other stuff that I drew on the CGContext through it).
As I mentioned, this way of setting the fill color assumes that the color is in the same color space as the context.
Normally, most CGContexts are in an RGB color space. whiteColor, on the other hand, is almost certainly in a white color space, which has only one or two (white and alpha) components.
So, since the context is in an RGB color space, CGContextSetFillColor expects to be passed three or four (red, green, blue, and alpha) components. When you get the components of whiteColor's CGColor, you get a pointer to a C array holding only two components. CGContextSetFillColor will read the three or four components it wants no matter what; if you pass fewer, it may find garbage after them, or it may find zeroes.
If it finds a zero in the alpha position, then the result is that you have set the fill color to something between yellow (red=1.0, green=1.0, blue=0.0) and white (all three=1.0) with zero alpha. That's what causes the fill to not show up: You are filling with a transparent color.
The problem is that mismatch between the color space the context is in (with three or four components) and the color space the color is in (with one or two components). The solution is to remove the mismatch, which is what CGContextSetFillColorWithColor does: Since you are passing the whole CGColor object, not just an array of numbers, Core Graphics will be able to set the context's color space to that of the color object and interpret the color object's components correctly.

iphone: How can I remove the red colors from an image? (RGB colors)

Let's say I have an UIImageView, and I wanna show only blue and green colore from it, (RGB colors). Like in Photoshop, I can choose what colors to show, red, blue, and green, so in the image to delete the red color.
So how can I do it? I really new in Objective-c and all :)
There are many ways to do this. If you have access to the image bitmap data, you can just set the red channel to zero on all the pixels. You might need to draw the image into a CGBitmapContext, get the pointer to the bitmap data, and then create a new CGImage that gets turned into a UIImage.
Or you can create a UIView subclass with a custom drawRect: method which first draws the image normally, and then draws a color set to RGB (0, 1, 1) with the blend mode (set by CGContextSetBlendMode) to kCGBlendModeMultiply.

GLPaint with white background

I'm trying draw on a white background by reverse engineering GLPaint. I've gone through every combination of kSaturation, kLuminosity and glBlendFunc, AND just about every combination I can think of for brush texture (black on white, white on black, white on trans, alias/no alias, etc), but haven't stumbled upon the desired effect.
The best I've been able to achieve is with a white-on-trans circle, with glBlendFunc (GL_ SRC_ ALPHA, GL_ ONE_ MINUS_ SRC_ ALPHA), but this still gives me a dull colour, and the semi-trans outer bits are interpreted as black (i.e. dull green with black edges, instead of vibrant green with transparent edges). It's as though it still assumes I'm on a black background.
Any advice?
(source: straandlooper.com)
Did you also:
glEnable(GL_BLEND);
?
I believe this is what you want for it to work on White:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Then use a white 'Particle.png' circle that feathers out to transparency (your 'best' example).
This should give in the desired result.
Yup, glEnable(GL_BLEND) is in there.
I've basically started with GLPaint and changed the background to white and the rest of the code is the same. I have to assume that since GLPaint was made with black background, there's some bit of code that is set to blend ideally to black, and I don't know which switch to flip (or, indeed, what switches can be flipped. Heck, what switches even exist).
Here's what's there by default. Lemme know if you see anything awry...
glDisable(GL_DITHER)
glMatrixMode(GL_PROJECTION)
glMatrixMode(GL_MODELVIEW)
glEnable(GL_TEXTURE _2D)
glEnableClientState(GL_VERTEX _ARRAY)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC _ALPHA, GL_ONE _MINUS _SRC _ALPHA)
glEnable(GL_POINT _SPRITE _OES)
glEnable(GL_COLOR _MATERIAL)
I don't mind telling you, I haven't a clue what any of that is.
-kev.