15

Hi I am try to capture a view then save as an image into Photo Library , but I need create a custom resolution for captured image , here is my code but when app saves the images the resolution is low !

UIGraphicsBeginImageContextWithOptions(self.captureView.bounds.size, self.captureView.opaque, 0.0);

[self.captureView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext();

CGRect cropRect = CGRectMake(0 ,0 ,1435 ,1435);
CGImageRef imageRef = CGImageCreateWithImageInRect([screenshot CGImage], cropRect);
CGImageRelease(imageRef);

UIImageWriteToSavedPhotosAlbum(screenshot , nil, nil, nil);

UIGraphicsEndImageContext();

but the resolution in iPhone is : 320 x 320 and retina is : 640 x 640

I would be grateful if you help me to fix this issue .

Atulkumar V. Jain
  • 5,102
  • 9
  • 44
  • 61
iOS.Lover
  • 5,923
  • 21
  • 90
  • 162
  • 1
    [SupportingHiResScreens](http://developer.apple.com/library/ios/#documentation/2DDrawing/Conceptual/DrawingPrintingiOS/SupportingHiResScreens/SupportingHiResScreens.html) > [Creating High-Resolution Bitmap Images Programmatically](http://developer.apple.com/library/ios/#documentation/2DDrawing/Conceptual/DrawingPrintingiOS/SupportingHiResScreens/SupportingHiResScreens.html#//apple_ref/doc/uid/TP40010156-CH15-SW9) – Bala Jul 11 '12 at 12:02
  • 1
    http://stackoverflow.com/a/613576/1059705 – Bala Jul 11 '12 at 12:09
  • 1
    what size of the image do you choose from the Photo Library? Larger or smaller than your desired size (1435, 1435)? – holex Jul 17 '12 at 07:50
  • 1
    @Mc.Lover try with processImageRect will definitely solve your issue. – Kuldeep Jul 17 '12 at 10:35
  • 1
    So what is in the view you want to create an image out of? Is it a photo taken by the camera, image from some other source such as downloaded from web? Or does your view have many sub-vies that has random things such as UIWebView + UIImageView + UILable + UISlider + UITableView + others? – Pareshkumar Jul 21 '12 at 23:17

9 Answers9

16

Your code is pretty close. What you need to do is re-render the screenshot at the custom resolution. I modified your code to do this:

UIView* captureView = self.view;

/* Capture the screen shoot at native resolution */
UIGraphicsBeginImageContextWithOptions(captureView.bounds.size, captureView.opaque, 0.0);
[captureView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

/* Render the screen shot at custom resolution */
CGRect cropRect = CGRectMake(0 ,0 ,1435 ,1435);
UIGraphicsBeginImageContextWithOptions(cropRect.size, captureView.opaque, 1.0f);
[screenshot drawInRect:cropRect];
UIImage * customScreenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

/* Save to the photo album */
UIImageWriteToSavedPhotosAlbum(customScreenShot , nil, nil, nil);

Note that if capture view is not square then the image will be distorted. The saved image will always be square and 1435x1435 pixels.

idz
  • 12,825
  • 1
  • 29
  • 40
7

have a look at this answer. The code includes rotation but nonetheless the questioner asked the same question: "How to get a […] image from an UIImageView at its full resolution?"

copied content (in case of deletion or whatever):

- (UIImage *)capturedView
{
    float imageScale = sqrtf(powf(self.captureView.transform.a, 2.f) + powf(self.captureView.transform.c, 2.f));    
    CGFloat widthScale = self.captureView.bounds.size.width / self.captureView.image.size.width;
    CGFloat heightScale = self.captureView.bounds.size.height / self.captureView.image.size.height;
    float contentScale = MIN(widthScale, heightScale);
    float effectiveScale = imageScale * contentScale;

    CGSize captureSize = CGSizeMake(enclosingView.bounds.size.width / effectiveScale, enclosingView.bounds.size.height / effectiveScale);

    NSLog(@"effectiveScale = %0.2f, captureSize = %@", effectiveScale, NSStringFromCGSize(captureSize));

    UIGraphicsBeginImageContextWithOptions(captureSize, YES, 0.0);        
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextScaleCTM(context, 1/effectiveScale, 1/effectiveScale);
    [enclosingView.layer renderInContext:context];   
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return img;
}
Community
  • 1
  • 1
1

First get your image in UIImage object. Create your size what ever you want and use following..

UIImage *image = // you image;
CGSize size;
if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] &&
([UIScreen mainScreen].scale == 2.0)) {

     // RETINA DISPLAY
      size = CGSizeMake(640, 640);
}
else {
     // Non Ratina device
      size = CGSizeMake(320, 320);
}

UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *destImage = UIGraphicsGetImageFromCurrentImageContext();    
UIGraphicsEndImageContext();

Now you will get destImage with new resolution.

Hope this is what you are looking for :)

Kapil Choubisa
  • 5,152
  • 9
  • 65
  • 100
  • 1
    the 320 and and 640 resolutions was the captured image resolution ! I need 1435 res both in retina and non retina display. – iOS.Lover Jul 11 '12 at 12:11
  • 3
    that won't be done dear.. you can do that by providing the image and size will be fixed using `CGSizeMake (1425, 1435)`. But your image quality will be very poor. – Kapil Choubisa Jul 11 '12 at 12:16
  • 4
    Just to reiterate the Kapil's comment - the display only has 320x480 or 640x960 pixels to show. You can render that into a much larger image, but the display's pixels will just be stretched to fill the image's size. There is no way to create a higher resolution image of what is on the display. That said, if you're displaying a high res image shrunk to fit the display, or a pdf, you COULD render those into a much larger image and get a high rez output. – David H Jul 15 '12 at 15:43
1
-(UIImage*)processImageRect:(UIImage*)image:(CGSize)sizeToForm {
    // Draw image1  
    UIGraphicsBeginImageContext(CGSizeMake(sizeToForm.width, sizeToForm.height));  
    [image drawInRect:CGRectMake(0.0, 0.0, sizeToForm.width, sizeToForm.height)]; 
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();

    return resultingImage;
}

Go with this may solve your issue.

Kuldeep
  • 2,589
  • 1
  • 18
  • 28
1

You can use that :

UIImageExtras.h

@interface UIImage (Extras)
-(UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize;
@end

UIImageExtras.m

#import "UIImageExtras.h"

@implementation UIImage (Extras)

- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
{
//Image de base
UIImage *sourceImage = self;
//Image redimenssionnée
UIImage *newImage = nil; 

//Taille de l'image de base
CGSize imageSize = sourceImage.size;
//Longueur et largeur 
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;

//Dimension désirée
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;

//Echelle...
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

//Si taille des image est différentes on redimensionne de facon proportionnelle
if (CGSizeEqualToSize(imageSize, targetSize) == NO) 
{
    CGFloat widthFactor = targetWidth / width;
    CGFloat heightFactor = targetHeight / height;

    if (widthFactor > heightFactor)
        scaleFactor = widthFactor; // scale to fit height
    else
        scaleFactor = heightFactor; // scale to fit width
    scaledWidth  = width * scaleFactor;
    scaledHeight = height * scaleFactor;

    //Centre l'image
    if (widthFactor > heightFactor)
    {
        thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 
    }
    else if (widthFactor < heightFactor)
        {
            thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
        }
    }       

    UIGraphicsBeginImageContext(targetSize);

    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width  = scaledWidth;
    thumbnailRect.size.height = scaledHeight;

    [sourceImage drawInRect:thumbnailRect];

    newImage = UIGraphicsGetImageFromCurrentImageContext();
    if(newImage == nil) 
        NSLog(@"could not scale image");

    UIGraphicsEndImageContext();

    return newImage;
}
@end
An-droid
  • 6,433
  • 9
  • 48
  • 93
1

This worked for me. I tried with image that i got from Facebook SDK http://pulkitgoyal.in/resizing-high-resolution-images-on-ios-without-memory-issues/

0

I think ALAssetRepresentation can help you.

Mathew Varghese
  • 4,527
  • 2
  • 17
  • 26
0
CGSize sizePic = CGSizeMake(320, 460);
    UIGraphicsBeginImageContext(sizePic);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *imagePic = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    UIImageWriteToSavedPhotosAlbum(imagePic, nil, nil, nil);
chineseGirl
  • 179
  • 1
  • 1
  • 8
0
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h> 

+ (UIImage *)resizeImage:(UIImage *)image toResolution:(int)resolution {
NSData *imageData = UIImagePNGRepresentation(image);
CGImageSourceRef src = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
CFDictionaryRef options = (__bridge CFDictionaryRef) @{
                                                       (id) kCGImageSourceCreateThumbnailWithTransform : @YES,
                                                       (id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
                                                       (id) kCGImageSourceThumbnailMaxPixelSize : @(resolution)
                                                       };
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
CFRelease(src);
UIImage *img = [[UIImage alloc]initWithCGImage:thumbnail];
return img;

}

Vineet Ravi
  • 1,457
  • 2
  • 12
  • 26