Custom Drawing of Alpha Images - iphone

I am trying to do custom drawing of an image(with alpha) and eventually going to apply different color tints to it. Right now I am just trying to draw it correctly. This might be simple problem but the result is the ALPHA on my image is black. Image is .png created from photoshop with correct alpha.
- (void) drawRect:(CGRect)area
{
[imgView.image drawInRect: area blendMode:blendMode alpha:alpha]; // draw image
}
blendMode is normal and alpha is 1.0. The image is good except alpha being black. Any help appreciated.
Tried another method of drawing, but shows black alpha and upside down(don't care about it being upside right now tho)
- (void) drawRect:(CGRect)area
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
// Draw picture first
CGContextDrawImage(context, area, imgView.image.CGImage);
CGContextRestoreGState(context);
}

[imagename drawInRect:CGRectMake(x, y, width, height)];
or
[imagename drawAtPoint:CGPointMake(x, y)];

I believe that when you use drawInRect:blendMode:alpha, the alpha that you pass in overrides the alpha in your image. The documentation I just looked at wasn't quite clear.

Related

Filling Colors inside edges

I am new to Iphone development.
Currently i am making coloring app.
I am using apple's paint app as ref to create my app.
I successfully create app where u can color on a screen with given texture image
What i did is
I create a custom UIView which extends opengl and i detect touches on it and draw accordingly.
I also kept background UIImageView which contain outline images, so it feels like your drawing above that Image.
Everything works fine
but i wanted to fill color inside black edges
Like if a image has four square which has black edges and inside of that square is blank and if i touch any square it should fill that square with selected color(mostly i am working on irregular shape)
Can anyone tell me how can i fill colors inside that square
The flood fill algo looks slow as i have some big images which will take time to fill the color
so is there any easy method by which i can fill color
A sample code will b very helpful as i am new to iPhone Dev
I implemnted this kind of feature in my recent project. The difference is: I filled color in border only.
Check my code over here, it might get helpful to you
// apply color to only border & return an image
+ (UIImage *)imageNamed:(NSString *)name withColor:(UIColor *)color
{
// load the image
UIImage *img = [UIImage imageNamed:name];
// begin a new image context, to draw our colored image onto
UIGraphicsBeginImageContext(img.size);
// get a reference to that context we created
CGContextRef context = UIGraphicsGetCurrentContext();
// set the fill color
[color setFill];
// translate/flip the graphics context (for transforming from CG* coords to UI* coords
CGContextTranslateCTM(context, 0, img.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// set the blend mode to color burn, and the original image
CGContextSetBlendMode(context, kCGBlendModeColorBurn);
CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);
CGContextDrawImage(context, rect, img.CGImage);
// set a mask that matches the shape of the image, then draw (color burn) a colored rectangle
CGContextClipToMask(context, rect, img.CGImage);
CGContextAddRect(context, rect);
CGContextDrawPath(context,kCGPathFill);
// generate a new UIImage from the graphics context we drew onto
UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//return the color-burned image
return coloredImg;
}
Enjoy Programming !

Merge image on double Tap

I have two ImageViews and I am merging two images. First image is a bodyImage and second Image is a tattooImage. I already done merging, but I wants ask
1)I can drag tattooImage over bodyImage. I wants on doubleTap tattooImage mergeWith bodyImage on the tap coordinates. Hope you understand question
Thanks
+ =
and here is my code : here imageView1 is my bodyImage and imageView2 is my tattooImage
- (void)tapDetected:(UITapGestureRecognizer *)tapRecognizer
{
int width=500;
int height=500;
NSLog(#"takephoto from twitter");
CGSize newSize = CGSizeMake(width, height);
UIGraphicsBeginImageContext( newSize );
// Use existing opacity as is
[imageView1.image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
// Apply supplied opacity if applicable
[imageView2.image drawInRect:CGRectMake(180,200,200,200) blendMode:kCGBlendModeDarken alpha:0.4];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
imageView1.image=newImage;
UIGraphicsEndImageContext();
}
mask image http://www.developers-life.com/resize-and-mask-an-image.html
You need image masking for that. I wrote a tutorial on how to use it, and how I've used it in my own application. From the Apple documentation:
Masking techniques can produce many interesting effects by controlling which parts of an image are painted. You can:
Apply an image mask to an image. You can also use an image as a mask
to achieve an effect that’s opposite from applying an image mask.
Use color to mask parts of an image, which includes the technique
referred to as chroma key masking.
Clip a graphics context to an
image or image mask, which effectively masks an image (or any kind of
drawing) when Quartz draws the content to the clipped context.

CGContextFillEllipseInRect acting weird

Here is my drawRect:
- (void)drawRect:(CGRect)rect
{
CGContextFillEllipseInRect(UIGraphicsGetCurrentContext(), self.bounds);
}
and the instances of this class are added a subviews the next way:
(#define DOTS_SIZE 30)
[self addSubview:[[VertexView alloc] initWithFrame:CGRectMake(anchor.x-DOTS_SIZE/2, anchor.y-DOTS_SIZE/2, DOTS_SIZE, DOTS_SIZE)]];
As far as I understand, I should get and ellipse (circle my case) in the views bounds. But I get it fully filled with rectangle (square).
By the way, I have logged bounds and their size is 30x30, so I should get nice little circles, but I get squares (T_T)
I'll be thankful for any advise!
The problem is that you have to make some setup before drawing the ellipse. For example:
- (void)drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor); // Or any other color.
CGContextFillEllipseInRect(ctx, self.bounds);
}
And to make background transparent you can check out: Setting A CGContext Transparent Background

How to use a CGBlendMode on a UIView that scrolls above a fixed background?

Our main UIView is a UIScrollView with a fixed background image (very common, obviously). In that scrollView, we have several UIViews that hold content and scroll up and down as the user scrolls (also common). Those UIViews each have their own background, a simple gradient from white to black.
The goal is to have the background gradient of those (inner) UIViews be partially opaque AND use a CGBlendMode other than "kCGBlendModeNormal" (specifically, "kCGBlendModeOverlay"). You should be able to see through to the "parent" scrollView’s fixed background image as the UIViews scroll up and down above it.
- (void)drawRect:(CGRect)rect {
gradientStart = [UIColor colorWithRed:1 green:1 blue:1 alpha:1.0];
gradientEnd = [UIColor colorWithRed:0 green:0 blue:0 alpha:1.0];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[2] = { 0.0f, 1.0f };
NSArray *colors = [NSArray arrayWithObjects:(id)gradientStart.CGColor, (id)gradientEnd.CGColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)colors, locations);
CGColorSpaceRelease(colorSpace);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetAlpha(context, 0.50); //this works!
CGContextSetBlendMode(context, kCGBlendModeOverlay); //doesn’t seem to do anything!
CGContextClearRect(context, rect);
CGPoint startPoint, endPoint;
startPoint.x = 0.0;
startPoint.y = 0.0;
endPoint.x = 0.0;
endPoint.y = rect.size.height;
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient);
[super drawRect:rect];
}
Everything works as expected except the CGContextSetBlendMode, which is ignored. We can't seem to find a way to change the blendMode of a UIView relative to what is behind it, the same way you can with alpha. Please note that this is different than building up multiple layers in a SINGLE UIView; in that case, this technique does change the blendMode of the layers "on top". We want to see through to the parent scrollView's fixed background image (as we scroll the child view up and down above it), with both an alpha and an overlay blend applied.
Here's an image showing the issue: http://img2.sbck.us/blendmode.png
Thanks in advance for your help!
I believe what you want is not possible with your current setup. On iOS, it is simply not possible for the blend mode of a view to have an effect on the stuff that is drawn under the view. You would have to draw the scroll view's background and the gradients in the same view.
This is possible, at least with two image views. It might even be possible with more general views. The approach is to implement drawRect in the parent view, and do as follows:
Determine the rect for the foreground view.
Convert the rect in the foreground view to a rect in the background view.
Begin a new graphics context.
Draw the background with the proper blend mode.
Draw the foreground with the proper blend mode.
Extract the image from the graphics context.
End the graphics context.
Use the extracted image accordingly.
This allows a foreground image to blend with a background image.
Seems like you could do this by setting the 'compositingFilter' property of your view's CALayer. The comment in CALayer.h says "A filter object used to composite the layer with its (possibly filtered) background. Default value is nil, which implies source-over compositing."
Alas, CoreImage which provides the filters is not (officially) available on iOS.
I guess your other alternative would be to use OpenGL. You could still use UIView with OpenGL after a fashion by rendering your UIView's into images which could then be used a textures.

iPhone: How to change the color of an image

I have a small image from a database and the image's average color need to be altered slightly.
It's a CGImageRef and I thought of creating a CGContext, drawing the image to this context, then subsequently changing the bitmap data somehow and finally rendering it.
But how can I alter the color information?
Thanks for your help!
Check out this Apple Q&A on pixel data manipulation for details on how you might go about that.
Draw a color onto the object like this:
// first draw image
[self.image drawInRect:rect];
// prepare the context to draw into
CGContextRef context = UIGraphicsGetCurrentContext();
// set the blend mode and draw rectangle on top of image
CGContextSetBlendMode(context, kCGBlendModeColor);
CGContextClipToMask(context, self.bounds, image.CGImage); // this restricts drawing to within alpha channel
CGContextSetRGBFillColor(context, 0.75, 0.0, 0.0, 1.0); // this is your color, a light reddish tint
CGContextFillRect(context, rect);
I put this into the drawRect: method of a custom UIView. That UIView has an ivar, UIImage *image that holds the image you want to tint or color.