images in Collection View are bad quality - ios

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];

Related

IOS: Make round thumbnail of image for tableview

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;

UIView drawViewHierarchyInRect giving pixelated results?

I'm using -drawViewHierarchyInRect:afterScreenUpdates: to draw a view into a UIImage, but it seems no matter what I do the results is always a very low resolution, because the image seems to need to be the same size as the original view?
The UIView is the size of the screen (in this case, 375 x 667), and the content scale factor is 2.0f.
But when I use -drawViewHierarchyInRect:afterScreenUpdates: to draw the view onto the image, it is resized (horribly) to this resolution, even though the contents is a much higher resolution.
I'm using UIGraphicsBeginImageContextWithOptions with a scale of 0.0 to create the image, so I assumed it should draw nicely, but no go. How do you draw the view hierarchy and not lose the detail?
Edit:
Here's some example code (from the answer below, which is giving the same result). It's giving me terribly down-scaled results when trying to draw the UIView hierarchy which includes a high res image:
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0);
[self.view drawViewHierarchyInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) afterScreenUpdates:NO];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.frame = self.view.bounds;
[self.view addSubview:imgView];
[self.view bringSubviewToFront:imgView];
This code works perfectly. It takes screenshot of current view and puts it to new created UIImageView. Please check that
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0);
[self.view drawViewHierarchyInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) afterScreenUpdates:NO];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.frame = self.view.bounds;
[self.view addSubview:imgView];
[self.view bringSubviewToFront:imgView];

UITableView and thumbnails

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.

I want to move to the left edge of the cell, the image

I was displaying an image on UITableviewcell.
I'm getting in the URL image.
I'm getting asynchronously image.
There is a blank space on the left side of the image.
I want to remove the margin on the left side of the image.
Thanks.
It may be because of UITableView . Try like this
if ([table respondsToSelector:#selector(setSeparatorInset:)]) {
[table setSeparatorInset:UIEdgeInsetsZero];
}
step 1
Create a custom UITableViewCell
step 2
place the image View on one edge
step 3
since the picture is coming asynchronously, there may be a problem of getting actual image size. to avoid this prob.
scale the image in the size you want it to be.
using this snippet
-(UIImage*)imageWithImage:(UIImage*)image
scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
You can do something like this if space is not part of image..
UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 60, 60)];
img.image = [UIImage imageNamed:#"one.png"];
[cell addSubview:img];

merge 2 images into one just like instagram

I am trying to figure out to get a single image pit of 2 image views like instagram
These are the 2 images. Thanks in advance.
UIImageView *photoImageView = [[UIImageView alloc] initWithFrame:CGRectMake(20.0f, 42.0f, 280.0f, 280.0f)];
[photoImageView setBackgroundColor:[UIColor blackColor]];
[photoImageView setImage:self.image];
[photoImageView setContentMode:UIViewContentModeScaleAspectFit];
//Add overlay
UIImage *overlayGraphic = [UIImage imageNamed:#"chiu"];
UIImageView *overlayGraphicView = [[UIImageView alloc] initWithImage:overlayGraphic];
overlayGraphicView.frame = CGRectMake(30, 100, 260, 200);
[photoImageView addSubview:overlayGraphicView];
I'm not sure you can do this directly with just a UIImageView control. I think you're going to have to get into low-level drawing routines to get this done.
Option 1 (not recommended, just trying to answer the original question):
Have you tried placing the overlay UIImageView on top of the "main" UIImageView and setting its opacity to something less than 1 (say 0.4)? It's a crude hack, but it might get you somewhere.
Option 2 (probably the better path to travel):
Create an image context and then draw your "base" and "overlay" images on it. Then you'll have a UIImage you can output and will only need 1 UIImageView. Something like this (NOTE: this is a basic outline; you will need to add a LOT of time to get exactly what you want out of it!):
UIImage *baseImage = [UIImage imageNamed:#"base"];
UIImage *overlayImage = [UIImage imageNamed:#"overlay"];
UIGraphicsBeginImageContextWithOptions(baseImage.size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect rect = CGRectMake(0, 0, baseImage.size.width, baseImage.size.height);
CGContextDrawImage(context, rect, baseImage.CGImage);
CGContextDrawImage(context, rect, overlayImage.CGImage);
UIImage *combined = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Resources