How to let the text in a UILabel appear blurry? - iphone

Is there a way to achieve a blurry or glowing effect for the text? Or would I have to fetch the graphics context of the layer and then apply some kind of gauss algorithm on the pixels? I searched the documentation on this but it appears that shadows don't draw blurry and there's no method in NSString, UIFont or UILabel that could help to do it.

CGContextSetShadowWithColor can be (ab)used to draw blurred text. As it can be slow, it is best to draw it to a buffer and then reuse that:
UIFont *font = [UIFont systemFontOfSize:18.0f];
UIGraphicsBeginImageContext(CGSizeMake(200.0f, 50.0f));
CGContextSetShadowWithColor(UIGraphicsGetCurrentContext(), CGSizeMake(0.0f, -500.0f), 2.0f, [[UIColor blackColor] CGColor]);
[#"Blurred Text!" drawAtPoint:CGPointMake(5.0f, -500.0f) withFont:font];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[imageView setImage:image];
Old answer:
A simple option is to draw the text a number of times and offset the x/y coordinates by 1 each time. To speed it up you can cache it on an offscreen buffer.

You can intentionally position the label on a half pixel and you'll get a blurry effect. You won't have much control over it, but it will look blurry:
UILabel *labelOnWholePixel = [[UILabel alloc]
initWithFrame:CGRectMake(20.0f, 20.0f, 280.0f, 25.0f)];
[labelOnWholePixel setText:#"Whole Pixel"];
[labelOnWholePixel setBackgroundColor:[UIColor clearColor]];
UILabel *labelOnHalfPixel = [[UILabel alloc]
initWithFrame:CGRectMake(20.5f, 50.5f, 280.0f, 25.0f)];
[labelOnHalfPixel setText:#"Half Pixel"];
[labelOnHalfPixel setBackgroundColor:[UIColor clearColor]];
[[self view] addSubview:labelOnWholePixel];
[[self view] addSubview:labelOnHalfPixel];
I'm not sure, but it appears to me that the closer you are to the whole number in either direction, the clearer it gets, so you can control it a little.

Use photoshop or some other image editor to create a clear, blurry overlay. Save as a PNG. Load this PNG into an UIImageview and draw it on top of the UILabel. Adjust the alpha to alter the effect.
You could even create a specialized UILabel subclass to handle this with several degrees of blur.

Aside from antialiasing UILabel does not support blurring its text (or its shadow). You'll have to code it manually.

Related

Transparent UIImage

I am creating an iOS application in which I have added a simple UIImage. I want to add the transparency effect in image to show other images behind that main image. Tell me how I can achieve this effect?
Note: I don't want to change the opacity/alpha of image.
An alpha change is how you alter transparency. In addition to this, you would want to alter this on the view level not on to the UIImage directly. E.x:
[myImageView setImage:[UIImage imageNamed#"myImage.png"]];
[myImageView setAlpha:0.7f];
use images in png format with alpha channel in it: alpha channel is the layer that tells how many transparent each pixel is
how about this:
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f,0.0f,1024.0f,768.0f)];
self.imageView.backgroundColor = [UIColor colorWithRed:255 green:255 blue:255 alpha:0.5];
[self.view addSubview:self.imageView];
or set its alpha
imageView.alpha = 0.5;
But be sure to instantiate the imageView, as property then synthesize.

CALayer Border is appearing above subview (Z-order related, I think)

I have searched but could not find the reason for this behavior.
I have a UIButton whose image I am setting. Here is how the button should appear. Note that this is just a photoshop of the intended button design:
Essentially, it is a square custom UIButton with a white border and a little surrounding shadow. In the upper right corner, there is a "X" mark, that will be added programmatically as a subview.
Here is the screenshot of the button within the actual app. At this point, I have only added a shadow and the X mark as a subview:
How, when I try to add the white border, here is what it looks like:
It seems that the white border is appearing above the X mark sublayer. I don't know why.
Here is the code that I am using:
// selectedPhotoButton is the UIButton with UIImage set earlier
// At this point, I am adding in the shadow
[selectedPhotoButton layer] setShadowColor:[[UIColor lightGrayColor] CGColor]];
[[selectedPhotoButton layer] setShadowOffset: CGSizeMake(1.0f, 1.0f)];
[[selectedPhotoButton layer] setShadowRadius:0.5f];
[[selectedPhotoButton layer] setShadowOpacity:1.0f];
// Now add the white border
[[selectedPhotoButton layer] setBorderColor:[[UIColor whiteColor] CGColor]];
[[selectedPhotoButton layer] setBorderWidth:2.0];
// Now add the X mark subview
UIImage *deleteImage = [UIImage imageNamed:#"nocheck_photo.png"];
UIImageView *deleteMark = [[UIImageView alloc] initWithFrame:CGRectMake(53, -5, 27, 27)];
deleteMark.contentMode = UIViewContentModeScaleAspectFit;
[deleteMark setImage:deleteImage];
[selectedPhotoButton addSubview:deleteMark];
[deleteMark release];
I don't understand why the border is appearing above the deleteMark subview. Is there any way to get the intended effect?
Thank you!
From Apple's docs on CALayer:
The border is drawn inset from the receiver’s bounds by borderWidth. It is composited above the receiver’s contents and sublayers and includes the effects of the cornerRadius property.
In order to get the effect you want, I suggest you put the image into an own subview/sublayer and set that sublayer's borderWidth property.
You can set the layer's zPosition to -1. That worked for me.
I had similar problem (I wanted to prevent border line to be on top of my subviews)
CAShapeLayer * _border = [CAShapeLayer layer];
_border.strokeColor = [UIColor colorWithRed:119/255.0f green:119/255.0f blue:119/255.0f alpha:1.0f].CGColor;
_border.fillColor = nil;
[bgRoundView.layer addSublayer:_border];
_border.path = [UIBezierPath bezierPathWithRoundedRect:bgRoundView.bounds cornerRadius:20.f].CGPath;

How to programmatically render a flat background UIColor as the background for a UIToolbar?

So I followed a tutorial which allows me to subclass UIToolbar and draw an image as a custom background for the UIToolbar.
Code was something like this:
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
UIImage *backgroundImage = [UIImage imageNamed:#"toolbar_background.png"];
[backgroundImage drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
This works flawlessly. Considering though that I just want my toolbar background to be a flat color. Basically something like [UIColor blackColor], is there an easier way to do this in the drawRect method?
Having to make a 320 x 44 px height flat black background image and use that with the above code seems like extreme overhead when [UIColor blackColor] is available? I'm just not sure how to implement it here.
I thought about doing something like this instead:
- (void)drawRect:(CGRect)rect
{
UIView *test = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.frame.size.width,self.frame.size.height)];
test.backgroundColor = [UIColor blackColor];
[self addSubview:test];
}
But this doesn't work because then the UIView COVERS all the UIToolbar items that I add later i.e the Toolbar is black yes, but the black is overtop all the toolbar items so they are not visible.
Is there a workaround?
Thanks.
You can create a flat UIToolbar without the need to create a subclass. Simply set BackgroundColor, BackgroundImage and ShadowImage.
[toolbar setBackgroundColor:[UIColor blackColor]];
[toolbar setBackgroundImage:[[UIImage alloc] init] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
[toolbar setShadowImage:[[UIImage alloc] init] forToolbarPosition:UIToolbarPositionAny];
Override the -drawRect: method as in your first example, but instead of drawing an image, use the UIRectFill method, like this:
[[UIColor blackColor] setFill];
UIRectFill(self.bounds);

How to draw text on image

i have a image. in that image i need to draw text.
pls provide any links or sample code to try it out.
Thanks for any help
Just composite an extra view containing the text on top of the image. If you use a UILabel with [UIColor clearColor] for the background color and set opaque to false you will just see the text on top of the image and none of the image will be obscured.
If you want to get an image from the image in a view with the transparent view containing text on top of it, see this answer:
How to obtain a CGImageRef from the content of an UIView?
Something like this:
UIView* baseView = [[UIView alloc] initWithFrame:frameSize];
UIImage* imageToCaption = [UIImage imageNamed:#"myImage.jpg"];
UIImageView* imageToCaptionView = [[UIImageView alloc] initWithImage:imageToCaption];
imageToCaptionView.frame = frameSize;
[baseView addSubview:imageToCaptionView];
[imageToCaptionView release];
// do stuff with fonts to calculate the size of the label, center it in your image etc. etc.
CGRect labelFrame = ...
UILabel* myLabel = [[UILabel alloc] initWithFrame:labelFrame];
myLabel.backgroundColor = [UIColor clearColor];
myLabel.opaque = NO;
// set the color, font, text etc.
[baseView addSubView:myLabel];
[myLabel release];
Not compiled or complete but you get the idea. If you wanted to get the result as an image you would use do [baseView.layer renderInContext:context];

"Masking" an animation? iPhone SDK

I have been looking into ways of masking images on the iPhone. I came across this solution
http://iosdevelopertips.com/cocoa/how-to-mask-an-image.html
which works great for still images. What I want to do is mask an animation in a UIImageView. From what I have read I don't think this is possible whilst also achieving a decent frame rate.
This leads me to ask whether the following is possible, could I "clip" the images inside the UIImageView? ie not re-size the UIImageView to the size of the images so some parts are chopped off?
I haven't tried this for performance, but you can use a Core Animation layer as a mask. You can define a path to use in a CAShapeLayer and fill the shape. Then specify the layer mask of your UIImageView's layer. Something like:
CGMutablePathRef path = CGPathCreateMutable();
// build the path by adding points
// ...
CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
[shapeLayer setPath:path];
[shapeLayer setFillColor:[[UIColor blackColor] CGColor]];
// Set shape layer bounds and position
// ...
// Set the mask for the image view's layer
[[imageView layer] setMask:shapeLayer];
Keep in mind that this isn't actually creating a new image as the link you reference does. This just creates a mask for display over top of your image view--which may not be what you want.
I searched high and low and finally found a solution with practically no limitations at all. So, here you go:
UIImageView *maskeeImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"MaskeeImage.png"]];
[maskeeImage setAnimationRepeatCount:-1];
[maskeeImage setAnimationImages:[[NSArray alloc] initWithObjects:[UIImage imageNamed:#"MaskeeImage1.png"], [UIImage imageNamed:#"MaskeeImage2.png"], [UIImage imageNamed:#"MaskeeImage3.png"], nil]];
[maskeeImage startAnimating];
CALayer *maskeeLayer = [maskeeImage layer];
maskeeLayer = CGRectMake(0, 0, 768, 1004);
[[[self view] layer] addSublayer:maskeeLayer];
UIImage *maskImage = [UIImage imageNamed:#"ImageMask.png"];
CALayer *maskLayer = [CALayer layer];
maskLayer.contents = (id) myImageMask.CGImage;
maskLayer.frame = CGRectMake(0, 0, 768, 1004);
[maskeeLayer setMask:maskLayer];
There you go! It's actually really easy, once you know how. I tried to show a few different options; Using UIImageViews or UIImages, Animations (Which can also be used for the mask).
To sum it all up, you basically have to set the mask property on your view's CALayer. Every UIView subclass has a CALayer attached to it, so you aren't restricted at all in terms of where you get your mask or maskee from.
Hope this helped. Cheers, Dylan.