Quartz shadows not drawing correctly - iphone

So, I've got this image for my app that looks like this:
Now this is nice and all, but I'm trying to reduce my dependency on images and instead try to draw this dynamically.
Okay, so I found this image built into UIColor: (scrollViewTexturedBackgroundColor)
Looks kinda light, but sweet. We're getting there.
So now, I override drawRect in a UIView subclass to darken that a bit.
-(void)drawRect:(CGRect)rect {
[[UIColor colorWithWhite:0.0 alpha:0.4] setFill];
UIRectFillUsingBlendMode(rect , kCGBlendModeDarken);
}
Hey, it's not perfect but it's close enough. I can always tweak the blending mode & color later. Now comes the hard part. I can't figure out how to get the shadows to draw correctly. For example, I tried to set my shadow like this:
CGContextSetShadowWithColor(ctx, CGSizeMake(0, 6), 5, [[UIColor blackColor]CGColor]);
However, the shadow doesn't display. Also, I tried saving the graphics state, applying the shadow, then restoring it, but when I did that the shadow appeared but with the color in reverse (probably due to the blending mode I set). Obviously that's not what I'd hoped.
Any ideas?

The shadow is rendered with something that is drawn. You cannot draw just a shadow without actual object which drops it. If you find a way to do it, please let me know.
I see on the first picture you use inner shadow effect. To have a similar result you need to draw a path that drops a shadow around the area.
On the picture the red path is a bezier path with stroke of 10px. I have left a thing gap between the picture and the path to show that the path is bigger than the background picture.
To generate such a path you can use a bezier path with rect. Inset the the background picture rect by negative value that equals a half of the stroke width.
If the actual context is bigger then the picture, clip it with the picture rect before drawing the path.

Related

Clear image with fade border

I have two UIImageView with same frame. One imageView above second imageView now I'm erasing upper imageView using Core Graphics. My problem is that the border of eraser is very sharp I want faded border i.e. after erasing the upper image should match the lower one's pallet. See below example -
I used these two images and below is result -
As you can see in this image eraser's border is very sharp. I want to make it faded out like in the middle it should be dark then light then more light and so on i.e. we cant see the width and end of brush. And here is my - My Sample Code Let me know if my question is not clear enough.
You can have a png image like brush (dark in the middle and light in the corner) and draw the image over your image like this.
[eraser drawAtPoint:location blendMode:kCGBlendModeDestinationOut alpha:1];

Adding a Border to UIimage

I have a few questions on adding border to UIimage :
1) Is there anyway to add a dynamic border to an image of uiimageview?? I have tried to add border by using [layer setBorderColor:[UIColor whiteColor].CGColor]; But the border just shows around the frame of the uiimageview (a square or a rectangle). All my images are with thick black outlines and custom shape(such as hellokitty), I would like to add borders around the outlines. Is that possible to do it???
(I have also tried to add shadow around the images, but the result is too blurry, anyway to make them solid?? I think thats another way to solve my problem)
2) Also, if I can draw a custom shape border to stick around the images, is that possible to fill in color inside the border??, because some of my images have no filled color, any ideas??
Thanks in advance.
If your images are transparent with random shapes (i.e. the outline of the image is the shape of hello kitty) then I would approach this by...
First, ignore UIImageView here. Prob easier to create a custom UIView subclass.
In the drawRect of your view...
- (void)drawRect:(CGRect)rect
{
// calculate the rect of the image (aspect ratio etc...) so that it fits in the rect.
// see this link https://stackoverflow.com/questions/7645454/resize-uiimage-by-keeping-aspect-ratio-and-width
// change the colour of the image to black (or the border colour you want).
// see this link http://coffeeshopped.com/2010/09/iphone-how-to-dynamically-color-a-uiimage
// draw the black image in the rect you calculated
// make a new rect that is smaller by in x and y than the one for the black image.
// You can change it by different amounts to change the border size
// draw the colour image in the new rect
}
Each step requires quite a bit of code so I've only put links and suggestions but this is what I'd do if I was trying to do what you are doing.
Link 1 - Resize UIImage by keeping Aspect ratio and width
Link 2 - http://coffeeshopped.com/2010/09/iphone-how-to-dynamically-color-a-uiimage

UIImage drawAtPoint after CGContextClip

I use ABUITableViewCell and draw all content manually. Also I use CGContextClip to make rounded corners, all works great, but when I tried to draw another image outside clip rect it hasn't been displayed.
When I draw NSString I use CGContextSaveGState(context) function and text will be shown. But the image is not.
How to draw image after CGContextClip?
You should store the state and then make sure you restore it afterward. Just draw the image after the CGContextRestoreGState.
If that's already what you're describing, then you may just be drawing the image in the wrong place.
You should make sure all save state calls you make are balanced by restores.

Does Quartz for iPhone draw non visible portions of a view?

I am wondering which is the best way, in terms of speed and efficiency, to draw a frame around an image on iPhone, especially when I have to draw lots of these images:
1) Drawing the image and then the frame around
or
2) Drawing a rect, filling it with a color and then drawing the image within that rect leaving some offset pixel to mimic the frame
Does Quartz draw everything that it is told to or is it smart enough to draw only what is really visible?
My feeling is that the first approach is better because there is actually less drawing done. Is it really so?
Thanks
P.
Quartz drawing will only take place within the bounds of the view, if you are doing custom drawing in -drawRect:.
That said, I think that you will see the best performance if you simply create UIImageViews for each image, then use the borderWidth, borderColor, and possibly cornerRadius properties on your view's layer to set a border. For example:
imageView.layer.cornerRadius = 10.0f;
imageView.layer.borderWidth = 3.0f;
imageView.layer.borderColor = [[UIColor blackColor] CGColor];
will place a 3-pixel-wide black border around your view, and give it a 10 pixel radius at the corners.
If performance is a problem, you should try to minimize the number of operations you perform on the graphics context, especially the ones that have no visible components.
In your particular case, I think you need to test both options on an iPhone (ist gen if possible) and benchmark them. Maybe it's easier to just fill the whole rectangle rather than calculate which pixels are part of the frame and which aren't?
It depends on the graphics chip.

Is there an easy way or library available to let text glow?

I'd like to make a glowing text that looks like if it was shining or emmitting light. Actually this would be done with some blurryness in the background. But I've found nothing in the iPhone SDK that would do it.
You can do this using pure Quartz drawing. Within -drawRect: for a UIView or -renderInContext: for a CALayer, the following code will draw text and apply a glow around it:
CGContextSetShadowWithColor( context, CGSizeMake( 0.0, 0.0 ), 20.0f, glowColor );
[text drawAtPoint:CGPointMake(0.5f, 0.5f) withFont:[UIFont fontWithName:#"Helvetica" size:16.0f]];
where text is an NSString, and glowColor is a CGColorRef for the glow you want to apply. This example will draw a glow that extends out 20 pixels from the 16-point Helvetica text, and is centered on the text.
You can easily convert this into a shadow by providing a different displacement (second argument in the first function) and by using a black CGColor for the shadow.
How about rendering the text into an initially transparent buffer using the desired glow colour, then apply a blur to it, and then render the text again over the top in the desired text colour.
Then you can draw the buffer wherever it needs to be.
See also the answers to "How do I create blurred text in an iPhone view?" which would suggest Cocoa Touch lacks any built in blur filters. You can write your own of course.
I created a simple iOS4 project based on answer above from Bard Larson and Cocoanetics on my blog, click here for further info and project source