I have been using variations of the following code in cellforrowatindexpath to make thumbnails for a tableview. However, I believe this code is unnecessarily complicated and stretches some images incorrectly. Can anyone please suggest the right way (i.e. efficient, consistent and non distorting) to make a round thumbnail (about 40x40) for display in a tableview? Thank-you:
//poor code
CGSize itemSize = CGSizeMake(40, 40);
UIGraphicsBeginImageContextWithOptions(itemSize, NO, UIScreen.mainScreen.scale);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[cell.imageView.image drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
cell.imageView.layer.masksToBounds=YES;
cell.imageView.layer.cornerRadius=20.0;
cell.imageView.frame = CGRectMake(20, 20, 500, 50);
//add image to right
return cell;
Note: Following approach from yah in this answer works for me in detail view but not in tableview controller cells
//does not work consistently. Sometimes images are square, sometimes round, sometimes football shaped
cell.imageView.layer.cornerRadius = cell.imageView.frame.size.width / 2;
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
cell.imageView.clipsToBounds = YES;
Related
I am displaying a list of images with names, with a chevron accessory to see the full size version of selected image.
I see that the scrolling performance is not super smooth. I think the reason is that the image I am assigning to the imageView of each cell is the full size image (which gets scaled down automatically before display).
Will the performance improve if I maintain a smaller image that is of "thumbnail" size? If yes, what is the best way to do this? I see some example in How to resize images in UITableViewCell?. Is the answer (reproduced below) that uses the approach below, good enough?
Also, any other tips to make the scrolling smoother?
CGSize itemSize = CGSizeMake(30, 30);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(30.0, 30.0, itemSize.width, itemSize.height);
[thumbnail drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Yes, scaling down image helps a lot. I created the method below to resize following (and call it on a background thread to keep main UI thread humming)
I also, found calling reloadData on only the row that changed helps using
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
Method used to downsize.
- (UIImage *) returnThumbnail:(UIImage*)image
{
CGSize itemSize = CGSizeMake(120, 90);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[image drawInRect:imageRect];
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSLog(#"Returning scaled image %#",scaledImage) ;
return scaledImage ;
}
The following code is working fine to make a square image round when placed in cellForRowAtIndexPath.
However, when I move the code to a custom cell, every time the tableview changes, it spreads the circle all the way across the table row into a horizontal blur.
//following crops and rounds image
CGSize itemSize = CGSizeMake(40, 40);
UIGraphicsBeginImageContextWithOptions(itemSize, NO, UIScreen.mainScreen.scale);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[self.iconView.image drawInRect:imageRect];
self.iconView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.iconView.layer.masksToBounds=YES;
self.iconView.layer.cornerRadius=20.0;
self.iconView.frame = CGRectMake(20, 20, 500, 50);
// [cell.iconView.image drawInRect:imageRect];
// cell.iconView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
In custom cell, I have been placing this code after the following:
self.iconview.image = [UIImage imageNamed:#"test.jpg"];
Does anyone know how I might fix this and still use a custom cell? Thanks in advance for any suggestions.
The issue is what "when I move the code to a custom cell" means - which you do not explain. But the problem is that iconView itself is being resized - it is being made wider. If you don't want that to happen, give it different constraints so that that doesn't happen.
There is no need for you to start the image context and get all the way down into CoreGraphics.
I accomplish this by:
imageView.image = myUIImage
imageView.layer.cornerRadius = imageView.bounds.size.width / 2
There is simple way to make rounded image in custom cell:
imageView.layer.cornerRadius = imageDemo.frame.size.width / 2;
imageView.clipsToBounds = YES;
or follow this link
I am trying to clip a UIImage to make it circular, I am starting with a 140*140px image and then running this code:
//round the image
UIImageView *roundView = [[UIImageView alloc] initWithImage:smallImage];
UIGraphicsBeginImageContextWithOptions(roundView.bounds.size, NO, 1.0);
[[UIBezierPath bezierPathWithRoundedRect:roundView.bounds
cornerRadius:roundView.frame.size.width/2] addClip];
[smallImage drawInRect:roundView.bounds];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
smallImage = finalImage;
//end round image
This works as desired but the quality is very low, the image looks fuzzy and the edges around the circle are jagged. I want to achieve them same affect as:
image.layer.cornerRadius = self.thumbnailView.frame.size.width / 2;
image.clipsToBounds = YES;
Not sure why the quality of the image is so low. Can someone give me some pointers please?
You might want to keep scale at 0.f, so it matches the device scale (retina / not retina).
UIGraphicsBeginImageContextWithOptions(roundView.bounds.size, NO, 0.f);
You can do also draw a circle like this:
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.f);
CGRect interiorBox = CGRectInset(rect, 0.f, 0.f);
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:insideBox];
[bezierPath addClip];
[image drawInRect:rect];
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
You are passing the wrong scale in to UIGraphicsBeginImageContextWithOptions. You are passing 1. Use UIGraphicsBeginImageContextWithOptions(roundView.bounds.size, NO, [UIScreen mainScreen].scale);
Are you sure you actually need to do this to the actual image? Would it not be enough to just make the image view rounded?
You can do this very easily.
UIImageView *imageView = // your image view with the image
imageView.frame = CGRectMake(0, 0, 140, 140); // the size you want
imageView.clipsToBounds = YES;
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.layer.cornerRadius = 70; // make the corner radius half of the size
This will display your image cropped into a circle by the image view.
The image remains the same. It is just the display of the image that is rounded.
It's much less expensive too (time and memory).
Doing this in a table will not slow it down. You only need to do this once for each of the dequeued cells. For reused cells you do not need to do this as it is done when the cell is first created.
I have a collection view with a bunch of images in it but the problem is that the images are very blurry and pixelated in the collection view. When I select one of the pictures, it shows a larger picture that makes it good enough quality to see. So I'm guessing its the scaling of the picture into a small cell that makes it bad quality in the collection view. How do I go about fixing the images so they don't look blurry/bad quality in the collection view?
The actual picture's size 640x853 and the cell size is 100x133.
this is what I have:
UIImage *theImage = [UIImage imageWithData:data];
UIGraphicsBeginImageContext(CGSizeMake( cell.frame.size.width, cell.frame.size.height));
[theImage drawInRect: CGRectMake(0, 0, cell.frame.size.width, cell.frame.size.height)];
UIImage *small = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *cellImageView = [[UIImageView alloc] initWithImage:small];
cell.backgroundColor = [UIColor whiteColor];
cell.clipsToBounds = YES;
[cell.contentView addSubview:cellImageView];
UITableView has UIImageView, all images has the same size. But when I starting scroll or selecting row, some images can change size. I cannot understand why. Or how to make an imageview of a fixed size in a table row?
Use UIGraphicsImageContext with the table view cell image view like :
UIImage *thumbNail = [UIImage imageNamed:[_imageArray objectAtIndex:indexPath.row]];
// Setting thumbnail image
CGSize itemSize = CGSizeMake(60, 40);// Sample image size
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[thumbNail drawInRect:imageRect];
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
You can do one thing.. Use custom cell and set imageView's frame there.