views:

1100

answers:

2

Hi all,

I am trying to add a curved border around an image downloaded and to be displayed in a UITableViewCell.

In the large view (ie one image on the screen) I have the following:

productImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:product.image]];
[productImageView setAlpha:0.4];

productImageView.frame = CGRectMake(10.0, 30.0, 128.0, 128.0);
CALayer *roundedlayer = [productImageView layer];
[roundedlayer setMasksToBounds:YES];
[roundedlayer setCornerRadius:7.0];
[roundedlayer setBorderWidth:2.0];
[roundedlayer setBorderColor:[[UIColor darkGrayColor] CGColor]];
[self addSubview:productImageView];

In the table view cell, to get it to scroll fast, an image needs to be drawn in the drawRect method of a UIView which is then added to a custom cell.

so in drawRect

- (void)drawRect:(CGRect)rect {

...

point = CGPointMake(boundsX + LEFT_COLUMN_OFFSET, UPPER_ROW_TOP);

//CALayer *roundedlayer = [productImageView layer];
//[roundedlayer setMasksToBounds:YES];
//[roundedlayer setCornerRadius:7.0];
//[roundedlayer setBorderWidth:2.0];
//[roundedlayer setBorderColor:[[UIColor darkGrayColor] CGColor]];
//[productImageView drawRect:CGRectMake(boundsX + LEFT_COLUMN_OFFSET, UPPER_ROW_TOP, IMAGE_WIDTH, IMAGE_HEIGHT)];
//      

[productImageView.image drawInRect:CGRectMake(boundsX + LEFT_COLUMN_OFFSET, UPPER_ROW_TOP, IMAGE_WIDTH, IMAGE_HEIGHT)];

So this works well, but if I remove the comment and try to show the rounded CA layer the scrolling goes really slow.

To fix this I suppose I would have to render this image context into a different image object, and store this in an array, then set this image as something like:

productImageView.image = (UIImage*)[imageArray objectAtIndex:indexPath.row];

My question is "How do I render this layer into an image?" TIA.

A: 

You are on the right track with your own comment.

- (UIImage *)roundedImage:(UIImage*)originalImage;
{
    CGRect bounds = originalImage.bounds;
    CGImageRef theImage = originalImage.CGImage;
    CALayer *roundedlayer = [CALayer layer];
    roundedlayer.position = CGPointMake(0.0f,0.0f);
    roundedlayer.bounds = bounds;
    [roundedlayer setMasksToBounds:YES];
    [roundedlayer setCornerRadius:7.0];
    [roundedlayer setBorderWidth:2.0];
    [roundedlayer setBorderColor:[[UIColor darkGrayColor] CGColor]];
    roundedlayer.contents = theImage;

    UIGraphicsBeginImageContext(bounds.size);       // creates a new context and pushes it on the stack

    CGContextBeginTransparencyLayerWithRect(UIGraphicsGetCurrentContext(), bounds, NULL);
    CGContextClearRect(UIGraphicsGetCurrentContext(), bounds);
    [roundedlayer drawInContext:UIGraphicsGetCurrentContext()];

    UIImage *anImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext();        //releases new context and removes from stack

    return anImage;
}

I would pre-render these and store them in your image array so they are not calculated during your drawRect, but set in your

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

method.

Chip Coons
Cool, that is almost it. Just one more thing: scaling the image down. - (UIImage *)roundedImage:(UIImage*)originalImage newWidth: (float) newWidth newHeight: (float) newHeight;CGRect bounds = CGRectMake(0.0,0.0,newWidth,newHeight);Hmmm... not sure of all the syntax. Checking with this link. http://www.gotow.net/creative/wordpress/?p=7
Either set the bounds as you have in your comment, or use the [UIImage drawInRect:] method when you put it into your tableViewCell with the dimensions you desire. It depends on if you will want a rounded version at different scales anywhere else.
Chip Coons
Unfortunately that code doesn't actually work. the compiler complains at: CGRect bounds = originalImage.bounds;and roundedlayer.contents = theImage;The first one I suppose should be:CGRect bounds = CGRectMake(0.0, 0.0, originalImage.size.width, originalImage.size.height);as for the second error, not sure yet.
A: 

This is what I got to work well.

- (UIImage *)roundedImage:(UIImage*)originalImage
{
    CGRect bounds = CGRectMake(0.0, 0.0, originalImage.size.width, originalImage.size.height);
    UIImageView *imageView = [[UIImageView alloc] initWithImage:originalImage];
    CALayer *layer = imageView.layer;
    imageView.frame = bounds;
    [layer setMasksToBounds:YES];
    [layer setCornerRadius:7.0];
    [layer setBorderWidth:2.0];
    [layer setBorderColor:[[UIColor darkGrayColor] CGColor]];
    UIGraphicsBeginImageContext(bounds.size);
    [layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *anImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext(); 
    [imageView release];

    return anImage;
}

Then to scale the image, I found this in the lazy loading example:

#define kAppIconHeight 48

    CGSize itemSize = CGSizeMake(kAppIconHeight, kAppIconHeight);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[image drawInRect:imageRect];
self.appRecord.appIcon = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();