How to set MediaItemArtwork Image Fill in UITableViewCell in iOS? - ios

I am trying to enter MPMediaItemArtwork Image into UITableView's cell's ImageView with following code.
MPMediaItemArtwork *artwork = [[[self.arrayOfAlbums objectAtIndex:indexPath.row] representativeItem]valueForProperty:MPMediaItemPropertyArtwork];
UIImage *artworkImage = [artwork imageWithSize: cell.imageView.bounds.size];
if (artworkImage)
{
cell.imageView.image = artworkImage;
}
else
{
cell.imageView.image = [UIImage imageNamed: #"noArtwork.png"];
}
It's okay when i insert Artwork image in UITableView's cell ImageView.
But when my artwork image is too small or big , it's happened like following pic.
Not in completely fill in cell's ImageView.
You see that? I want to set Fill with Stretch like iOS Music App
Here is Build-in App Artwork Image that set Completely fill with Stretch
I want to do like that.
So i used cell.imageView.contentMode = UIViewContentModeScaleAspectFill; however it's not effect.
So how can i do that?
Thanks you for your work.

Try this for calculating a new and fitting image;
Adjust newRect to the rect of your cell.
// scale and center the image
CGSize sourceImageSize = [artworkImage size];
// The rectangle of the new image
CGRect newRect;
newRect = CGRectMake(0, 0, 40, 33);
// Figure out a scaling ratio to make sure we maintain the same aspect ratio
float ratio = MAX(newRect.size.width / sourceImageSize.width, newRect.size.height / sourceImageSize.height);
UIGraphicsBeginImageContextWithOptions(newRect.size, NO, 1.0);
// Center the image in the thumbnail rectangle
CGRect projectRect;
projectRect.size.width = ratio * sourceImageSize.width;
projectRect.size.height = ratio * sourceImageSize.height;
projectRect.origin.x = (newRect.size.width - projectRect.size.width) / 2.0;
projectRect.origin.y = (newRect.size.height - projectRect.size.height) / 2.0;
[sourceImage drawInRect:projectRect];
UIImage *sizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
cell.imageView.image = sizedImage;

The line
UIImage *artworkImage = [artwork imageWithSize: cell.imageView.bounds.size];
creates an image with the size of the cell. So, it's scaled in this line and the image won't be bigger than the cell and therefore it will not scale afterwards.
I would leave the image at it's original size or at a size 2x the cell size and leave the scaling up to contentMode.
CGSize newSize = CGSizeMake(artwork.bounds.size.width, artwork.bounds.size.height)
UIImage *artworkImage = [artwork imageWithSize: newSize];

Related

The Image Size Issue Coming From Server In IOS

I am working on application in which the images are coming from server which i have to display in UIImageview which size is of screen size. the problem is some image resolution are very bigger. So, when I use AspectFill it does not appear properly, it is getting shrink and when I use AspectFit it appears in rectangle shape in image view . so is there any way to display image in UIImageView without getting shrink and without getting croped.
Thanks in advance
I think changing contentMode to UIViewContentModeScaleToFill of your imageView should help:
yourImageView.image = yourImage;
yourImageView.contentMode = UIViewContentModeScaleToFill;
CGRect frame = someImageView.frame;
frame.size = yourImage.size;
yourImageView.frame = frame;
Try this
-(UIImage*)resizeImage:(UIImage *)image imageSize:(CGSize)size
{
UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0,0,size.width,size.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
//here is the scaled image which has been changed to the size specified
UIGraphicsEndImageContext();
return newImage;
}
And then use new image for your imageView
You can set image using
UIImage * image=[UIImage imageNamed:#"image.png"];
CGSize size=CGSizeMake(50, 63);//set the width and height
UIImage resizedImage= [self resizeImage:image imageSize:size];
Hope it helps.
try :
UIImageView *yourImageView = [[UIImageView alloc] initWithFrame:CGRectMake(x, y, width, height)];
yourImageView.contentMode = UIViewContentModeRedraw;
yourImageView.image = yourImage;
i hope it helps.

ios 7:How to show images from photo album without strectch while placing it in uiimageview in larger size

My task is to get the images from photo album and show it in one ViewController which has one UIImageView in full screen. The problem am facing here is while showing the small size photos captured in camera are getting stretched when it comes to UIImageView
I have tried with all aspect mode for keeping the image as normal. but no luck
Thanks in advance!!
If you want the image selected from Photo Album with same size then
self.photoImgView.contentMode=UIViewContentModeScaleAspectFit;// is best
self.photoImgView.contentMode=UIViewContentModeScaleAspectFill; //if you want to fill the large imageview size with selected photo
self.photoImgView.contentMode=UIViewContentModeScaleToFill; // if you want to fill the large imageview size with selected photo
Else you can try with below solution for resizing image before assigning to imageview.
UIImage *uiImage=[info valueForKey:#"UIImagePickerControllerOrignalImage"];//UIImagePickerControllerEditedImage
CGSize size;
NSData *imageData;
imageData= UIImageJPEGRepresentation(uiImage, 1.0);
UIImage *galleryImage=[self squareImageWithImage:[UIImage imageWithData:imageData] scaledToSize:CGSizeMake(320, 320)];
photoImgView.image=galleryImage;
-(UIImage *)squareImageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
double ratio;
double delta;
CGPoint offset;
//make a new square size, that is the resized imaged width
CGSize sz = CGSizeMake(newSize.width, newSize.width);
//figure out if the picture is landscape or portrait, then
//calculate scale factor and offset
if (image.size.width > image.size.height) {
ratio = newSize.width / image.size.width;
delta = (ratio*image.size.width - ratio*image.size.height);
offset = CGPointMake(delta/2, 0);
} else {
ratio = newSize.width / image.size.height;
delta = (ratio*image.size.height - ratio*image.size.width);
offset = CGPointMake(0, delta/2);
}
//make the final clipping rect based on the calculated values
CGRect clipRect = CGRectMake(-offset.x, -offset.y,
(ratio * image.size.width) + delta,
(ratio * image.size.height) + delta);
//start a new context, with scale factor 0.0 so retina displays get
//high quality image
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(sz, YES, 0.0);
} else {
UIGraphicsBeginImageContext(sz);
}
UIRectClip(clipRect);
[image drawInRect:clipRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Hope it helps you..
Set the content mode of your image view. Try this:
imageView.contentMode = UIViewContentModeScaleAspectFit;
Hope this helps.. :)
I assume when you say
"I have tried with all aspect mode for keeping the image as normal. but no luck"
You mean you used the contentMode or UIImageView?
e.g.
self.myImageView.contentMode = UIViewContentModeScaleAspectFit;
or one of the others AspectFill is another common one fit letterboxes I think and fill scales past the edge until the entire screen is filled.
But if your image is too small then it is going to look stretched even if the aspect ratio is correct, as there just wont be enough data for a full image
I would use:
UIImageView *someImage = [UIImageView new];
someImage.contentMode = UIViewContentModeScaleAspectFill;
someImage.clipsToBounds = YES;

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.

Cropping and placing image to achieve battery level effect

I am trying to achieve the battery level effect by drawing on a plain battery image another cropped image based on current battery level.
At the moment I am able to change the colour of the empty battery image but I don't know how to crop, the new one, and place it on top of the original.
I've found some useful links on how to crop but, every single of them, is cropping from top-left corner of the image. I would like to have as a starting point the bottom-left and set the height according to current level.
In addition, it is possible to combine or place the cropped image on top of the original?
Here is my original image.
...and what I am trying to achieve
At the moment I am trying this code,
int width = emptyBm.size.width;
int height = fullBm.size.height * level / 100;
UIImage *image = [UIImage imageNamed:#"battery_icon"];
UIImage *image2 = [UIImage imageNamed:#"battery_icon_full"];
CGRect rect = CGRectMake(0, image.size.height-height, width, height);
CGImageRef imageRef = CGImageCreateWithImageInRect([image2 CGImage], rect);
CGImageRef actualMask = CGImageMaskCreate(CGImageGetWidth([image CGImage]),
CGImageGetHeight([image CGImage]),
CGImageGetBitsPerComponent([image CGImage]),
CGImageGetBitsPerPixel([image CGImage]),
CGImageGetBytesPerRow([image CGImage]),
CGImageGetDataProvider([image CGImage]), NULL, false);
CGImageRef masked = CGImageCreateWithMask(imageRef, actualMask);
batteryBackground.image = [UIImage imageWithCGImage:masked];
However, because I am using CGImageCreateWithImageInRect the cropped part is stretched
Use the gray battery image as mask. Create a green rectangle and apply the mask you created. Here is a link to iOS masking: link
EDIT:
I hope this works (not tested):
int width = emptyBm.size.width;
int height = fullBm.size.height * level / 100;
UIImage *image = [UIImage imageNamed:#"battery_icon"];
UIImage *image2 = [UIImage imageNamed:#"battery_icon_full"];
// For clarity, just pretend the mask method I gave link to you is defined in your class.
UIImage *maskedImage = [self maskImage:image2 withMask:image];
// I assume the two imageviews are already connected to outlets.
self.backgroundImageView = [[UIImageView alloc] initWithImage:image];
self.foregroundImageView = [[UIImageView alloc] initWithImage:maskedImage];
// Make it's image stick to bottom so it won't stretch.
self.foregroundImageView.contentMode = UIViewContentModeBottom;
// Then calculate the frame again to reflect changes of battery status.
CGRect rect = self.backgroundImageView.frame;
rect.size.height = height;
// Push the masked imageview a to bottom as amount of missing battery height.
rect.origin.y = rect.origin.y + self.backgroundImageView.frame.size.height - height;
self.foregroundImageView.frame = rect;

Image cropping issue in iOS

I am creating an iPhone app which has image cropping feature. In this, I am getting the photos from the UIImagePickerController and passing it for cropping. There it has a scrollview and the selected image will be added as a subview to the scrollview. And I am using a UIButton for selecting the area for cropping. User can move the button over the imageview and place it anywhere, and when click on CROP button, the area similar to the frame size of the button should be cropped from the imageview.
I used the following code, but it is not returning the actual image.
CGRect clippedRect = CGRectMake(self.scrollView.frame.origin.x+90, self.scrollView.frame.origin.y, self.scrollView.frame.size.width-180, self.scrollView.frame.size.height-220);
CGImageRef imageRef = CGImageCreateWithImageInRect([self.myPhoto CGImage], clippedRect);
UIImage *newImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
self.imageView.image = newImage;
also used
- (UIImage *)cropImage:(UIImage *)oldImage {
CGSize imageSize = self.cropFrame.frame.size;
UIGraphicsBeginImageContextWithOptions( CGSizeMake( imageSize.width, imageSize.height), NO, 0.);
[oldImage drawAtPoint:CGPointMake( xPosition, yPosition)
blendMode:kCGBlendModeCopy
alpha:1.];
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return croppedImage;
}
but the result image is not the exact image as per the button frame. I am getting the image from another area.
Updated code
- (void)loadPhoto{
CGFloat w = self.myPhoto.size.width;
CGFloat h = self.myPhoto.size.height;
CGRect imageViewFrame = CGRectMake(0.0f, 0.0f, roundf(w / 2.0f), roundf(h / 2.0f));
self.scrollView.contentSize = imageViewFrame.size;
UIImageView *iv = [[UIImageView alloc] initWithFrame:imageViewFrame];
iv.contentMode = UIViewContentModeScaleAspectFit;
iv.image = self.myPhoto;
[self.view addSubview:iv];
self.imageView = iv;
[iv release];
}
CGRect crop;//= CGRectMake(10, 10, 360, 360);
crop.origin.x = self.cropFrame.frame.origin.x;
crop.origin.y = self.cropFrame.frame.origin.y;
crop.size.width = roundf(self.cropFrame.frame.size.width * 2.0f); //self.cropFrame.frame.size.width * 2;
crop.size.height = roundf(self.cropFrame.frame.size.height * 2.0f); //self.cropFrame.frame.size.height * 2;
NSLog(#"Rect: %#", NSStringFromCGRect(crop));
self.imageView.image = [self croppedImage:crop];
- (UIImage *)croppedImage:(CGRect)bounds {
CGImageRef imageRef = CGImageCreateWithImageInRect([self.imageView.image CGImage], bounds);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:self.myPhoto.imageOrientation];
CGImageRelease(imageRef);
return croppedImage;
}
Please help to find a solution.
The iOS has a default feature for cropping images.Try this code.
picker.allowsEditing = YES;
and also check this controller for cropping..this is exactly the one you are looking for I think https://github.com/barrettj/BJImageCropper .Hope this helps you..
Since you are using a scrollView that allows the image to be scrolled, you need to adjust your crop rect to the scrollView's position:
float zoomScale = self.scrollView.zoomScale;
int cropX = (self.scrollView.contentOffset.x-imageView.frame.origin.x)/zoomScale;
int cropY = (self.scrollView.contentOffset.y-imageView.frame.origin.y)/zoomScale;
You could use this crop tool that I made. It essentially gives you an interface to allow the user to select the crop area. I think it is in line with that you are looking for.
https://github.com/nicholjs/BFCropInterface
Believing you have solve this problem. Me too had this when tried cropping functionality
Set image.size as the imageView.size & scrollView.contentSize. Below code will give the rect to crop
cropRect.origin = scrollView.contentOffset;
cropRect.size = scrollView.bounds.size;
cropRect.origin.x /= scrollView.zoomScale;
cropRect.origin.y /= scrollView.zoomScale;
cropRect.size.width /= scrollView.zoomScale;
cropRect.size.height /= scrollView.zoomScale;
If planning to show the full image first on visible rect. Setting the imageView.size & scrollView.contentSize to visible view size will give crop image of some other area. Instead try finding the zoom scale by
CGFloat dxWidth = viewCrop.frame.size.width / imageView.image.size.width;
CGFloat dxHeight = viewCrop.frame.size.height / imageView.image.size.height;
CGFloat zoomScale = fmaxf(dWidth, dHeight)
and apply (if by adding subView then after addSubView)
scrollView.minimumZoomScale = zoomScale; // to disable further zoom-out
[scrollView setZoomScale: zoomScale];

Resources