2012-05-08 22 views
6

Così ho cercato di capire cosa sto facendo di sbagliato da un po 'ora e non riesco a capirlo. Quello che sto cercando di realizzare è questo:UIImmaginamento delle dimensioni non funzionante correttamente

  1. scattare una foto con UIImagePickerController
  2. Prendete la foto risultante e ritagliare la parte superiore e inferiore in modo che diventi un quadrato (simile a Instagram)
  3. display che immagine all'interno di un UIButton

Per qualche motivo, ogni volta che prende la foto finisce falsata nel UIButton e sembra come se il ritaglio non funzionava correttamente. Ecco cosa faccio. All'interno del metodo didFinishPickingMediaWithInfo Ho il seguente codice:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{ 
    //Copy the image to the userImage variable 
    [picker dismissModalViewControllerAnimated:YES]; 
    userImage = nil; 

    //Rotate & resize image 
    userImage = [self resizeAndRotatePhoto:(UIImage *)[info objectForKey:UIImagePickerControllerOriginalImage]]; 
    NSLog(@"Userimage size, width: %f , height: %f", userImage.size.width , userImage.size.height); 

    //Update the image form field with the image and set the image in the controller 
    NSLog(@"Button size is height: %f , width: %f" , userImageAvatarButton.frame.size.height , userImageAvatarButton.frame.size.width); 
    [userImageAvatarButton.layer setMasksToBounds:YES]; 
    [userImageAvatarButton.layer setCornerRadius:3.0]; 
    [userImageAvatarButton setImage:userImage forState:UIControlStateNormal]; 
} 

includerò il metodo resizeAndRotatePhoto momentaneamente, ma il risultato è al di sotto. Inoltre, nel codice sopra, @property (strong) (UIImage *)userImage; è definito nel file di intestazione di ViewController. L'output del registro si traduce anche in:

2012-05-07 17:38:07.995 NewApp[10666:707] Userimage size, width: 1936.000000 , height: 1936.000000 
2012-05-07 17:38:08.000 NewApp[10666:707] Button size is height: 60.000000 , width: 60.000000 

Come si vede nell'immagine qui sotto, finisce distorto.
form with button

Per quanto riguarda il metodo di resizeAndRotate, qui è:

- (UIImage *)resizeAndRotatePhoto:(UIImage *)source 
{ 
if(source.imageOrientation == UIImageOrientationRight) 
{ 
    source = [self rotateImage:source byDegrees:90]; 
} 
if(userImage.imageOrientation == UIImageOrientationLeft) 
{ 
    source = [self rotateImage:source byDegrees:-90]; 
} 

CGFloat x,y; 
CGFloat size; 
if(source.size.width > source.size.height){ 
    size = source.size.height; 
    x = (source.size.width - source.size.height)/2; 
    y = 0; 
} 
else { 
    size = source.size.width; 
    x = 0; 
    y = (source.size.height - source.size.width)/2; 
} 


CGImageRef imageRef = CGImageCreateWithImageInRect([source CGImage], CGRectMake(x,y,size,size)); 
return [UIImage imageWithCGImage:imageRef]; 
} 

A questo punto non ho idea di come ottenere questa immagine di presentarsi senza distorsioni. Sembra che stia sbagliando e mostrandolo sbagliato nonostante il sistema abbia affermato che l'immagine è effettivamente un quadrato.

risposta

9

Ho abbandonato la soluzione vocaro.com per altri motivi (la soluzione si bloccherebbe se utilizzata con formati di immagini atipici, ad esempio CMYK).

Ad ogni modo, ora utilizzo il metodo imageByScalingAspectFillSize della seguente categoria UIImage per creare le miniature quadrate.

A proposito, questo applica automaticamente la scala della schermata principale del dispositivo (ad esempio il pulsante UIButton che è 60x60 punti su un dispositivo Retina, questo applicherà quella scala di 2x (o 3x), cioè 120x120 o Immagine 180x180).

UIImage + SimpleResize.h:

/* UIImage+SimpleResize.h 
* 
* Modified by Robert Ryan on 5/19/11. 
*/ 

@import UIKit; 

/** Image resizing category. 
* 
* Modified by Robert Ryan on 5/19/11. 
* 
* Inspired by http://ofcodeandmen.poltras.com/2008/10/30/undocumented-uiimage-resizing/ 
* but adjusted to support AspectFill and AspectFit modes. 
*/ 

@interface UIImage (SimpleResize) 

/** Resize the image to be the required size, stretching it as needed. 
* 
* @param size   The new size of the image. 
* @param contentMode The `UIViewContentMode` to be applied when resizing image. 
*      Either `UIViewContentModeScaleToFill`, `UIViewContentModeScaleAspectFill`, or 
*      `UIViewContentModeScaleAspectFit`. 
* 
* @return    Return `UIImage` of resized image. 
*/ 

- (UIImage * _Nullable)imageByScalingToSize:(CGSize)size contentMode:(UIViewContentMode)contentMode; 

/** Resize the image to be the required size, stretching it as needed. 
* 
* @param size   The new size of the image. 
* @param contentMode The `UIViewContentMode` to be applied when resizing image. 
*      Either `UIViewContentModeScaleToFill`, `UIViewContentModeScaleAspectFill`, or 
*      `UIViewContentModeScaleAspectFit`. 
* @param scale  The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen. 
* 
* @return    Return `UIImage` of resized image. 
*/ 

- (UIImage * _Nullable)imageByScalingToSize:(CGSize)size contentMode:(UIViewContentMode)contentMode scale:(CGFloat)scale; 

/** Crop the image to be the required size. 
* 
* @param bounds  The bounds to which the new image should be cropped. 
* 
* @return    Cropped `UIImage`. 
*/ 

- (UIImage * _Nullable)imageByCroppingToBounds:(CGRect)bounds; 

/** Crop the image to be the required size. 
* 
* @param bounds  The bounds to which the new image should be cropped. 
* @param scale  The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen. 
* 
* @return    Cropped `UIImage`. 
*/ 

- (UIImage * _Nullable)imageByCroppingToBounds:(CGRect)bounds scale:(CGFloat)scale; 

/** Resize the image to fill the rectange of the specified size, preserving the aspect ratio, trimming if needed. 
* 
* @param size The new size of the image. 
* 
* @return  Return `UIImage` of resized image. 
*/ 

- (UIImage * _Nullable)imageByScalingAspectFillSize:(CGSize)size; 

/** Resize the image to fill the rectange of the specified size, preserving the aspect ratio, trimming if needed. 
* 
* @param size The new size of the image. 
* @param scale The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen. 
* 
* @return  Return `UIImage` of resized image. 
*/ 

- (UIImage * _Nullable)imageByScalingAspectFillSize:(CGSize)size scale:(CGFloat)scale; 

/** Resize the image to be the required size, stretching it as needed. 
* 
* @param size The new size of the image. 
* 
* @return  Resized `UIImage` of resized image. 
*/ 

- (UIImage * _Nullable)imageByScalingToFillSize:(CGSize)size; 

/** Resize the image to be the required size, stretching it as needed. 
* 
* @param size The new size of the image. 
* @param scale The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen. 
* 
* @return  Resized `UIImage` of resized image. 
*/ 

- (UIImage * _Nullable)imageByScalingToFillSize:(CGSize)size scale:(CGFloat)scale; 

/** Resize the image to fit within the required size, preserving the aspect ratio, with no trimming taking place. 
* 
* @param size The new size of the image. 
* 
* @return  Return `UIImage` of resized image. 
*/ 

- (UIImage * _Nullable)imageByScalingAspectFitSize:(CGSize)size; 

/** Resize the image to fit within the required size, preserving the aspect ratio, with no trimming taking place. 
* 
* @param size The new size of the image. 
* @param scale The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen. 
* 
* @return  Return `UIImage` of resized image. 
*/ 

- (UIImage * _Nullable)imageByScalingAspectFitSize:(CGSize)size scale:(CGFloat)scale; 

@end 

UIImage + SimpleResize.m:

// UIImage+SimpleResize.m 
// 
// Created by Robert Ryan on 5/19/11. 

#import "UIImage+SimpleResize.h" 

@implementation UIImage (SimpleResize) 

- (UIImage *)imageByScalingToSize:(CGSize)size contentMode:(UIViewContentMode)contentMode { 
    return [self imageByScalingToSize:size contentMode:contentMode scale:0]; 
} 

- (UIImage *)imageByScalingToSize:(CGSize)size contentMode:(UIViewContentMode)contentMode scale:(CGFloat)scale { 
    if (contentMode == UIViewContentModeScaleToFill) { 
     return [self imageByScalingToFillSize:size]; 
    } 
    else if ((contentMode == UIViewContentModeScaleAspectFill) || 
      (contentMode == UIViewContentModeScaleAspectFit)) { 
     CGFloat horizontalRatio = self.size.width/size.width; 
     CGFloat verticalRatio  = self.size.height/size.height; 
     CGFloat ratio; 

     if (contentMode == UIViewContentModeScaleAspectFill) 
      ratio = MIN(horizontalRatio, verticalRatio); 
     else 
      ratio = MAX(horizontalRatio, verticalRatio); 

     CGSize sizeForAspectScale = CGSizeMake(self.size.width/ratio, self.size.height/ratio); 

     UIImage *image = [self imageByScalingToFillSize:sizeForAspectScale scale:scale]; 

     // if we're doing aspect fill, then the image still needs to be cropped 

     if (contentMode == UIViewContentModeScaleAspectFill) { 
      CGRect subRect = CGRectMake(floor((sizeForAspectScale.width - size.width)/2.0), 
             floor((sizeForAspectScale.height - size.height)/2.0), 
             size.width, 
             size.height); 
      image = [image imageByCroppingToBounds:subRect]; 
     } 

     return image; 
    } 

    return nil; 
} 

- (UIImage *)imageByCroppingToBounds:(CGRect)bounds { 
    return [self imageByCroppingToBounds:bounds scale:0]; 
} 

- (UIImage *)imageByCroppingToBounds:(CGRect)bounds scale:(CGFloat)scale { 
    if (scale == 0) { 
     scale = [[UIScreen mainScreen] scale]; 
    } 
    CGRect rect = CGRectMake(bounds.origin.x * scale, bounds.origin.y * scale, bounds.size.width * scale, bounds.size.height * scale); 
    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect); 
    UIImage *croppedImage = [UIImage imageWithCGImage:imageRef scale:scale orientation:self.imageOrientation]; 
    CGImageRelease(imageRef); 
    return croppedImage; 
} 

- (UIImage *)imageByScalingToFillSize:(CGSize)size { 
    return [self imageByScalingToFillSize:size scale:0]; 
} 

- (UIImage *)imageByScalingToFillSize:(CGSize)size scale:(CGFloat)scale { 
    UIGraphicsBeginImageContextWithOptions(size, false, scale); 
    [self drawInRect:CGRectMake(0, 0, size.width, size.height)]; 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return image; 
} 

- (UIImage *)imageByScalingAspectFillSize:(CGSize)size { 
    return [self imageByScalingAspectFillSize:size scale:0]; 
} 

- (UIImage *)imageByScalingAspectFillSize:(CGSize)size scale:(CGFloat)scale { 
    return [self imageByScalingToSize:size contentMode:UIViewContentModeScaleAspectFill scale:scale]; 
} 

- (UIImage *)imageByScalingAspectFitSize:(CGSize)size { 
    return [self imageByScalingAspectFitSize:size scale:0]; 
} 

- (UIImage *)imageByScalingAspectFitSize:(CGSize)size scale:(CGFloat)scale { 
    return [self imageByScalingToSize:size contentMode:UIViewContentModeScaleAspectFit scale:scale]; 
} 

@end 
+2

GRAZIE. Dopo ore e ore di frustrazione e ricerca online cercando vicino a 20 soluzioni proposte, questa è l'UNICA soluzione che ha funzionato. Molte grazie. – thephatp

+1

sì. mi ha risparmiato ore di lavoro pure. Apprezzo la categoria! – kevinl

Problemi correlati