web-dev-qa-db-fra.com

Recadrer un UIImage

J'ai du code qui redimensionne une image pour pouvoir obtenir une partie mise à l'échelle du centre de l'image. Je l'utilise pour prendre une variable UIImage et renvoyer une petite représentation carrée d'une image, similaire à celle vue dans la vue de l'album de l'application Photos. (Je sais que je pourrais utiliser UIImageView et ajuster le mode de recadrage pour obtenir les mêmes résultats, mais ces images sont parfois affichées dans UIWebViews).

J'ai commencé à remarquer des plantages dans ce code et je suis un peu perplexe. J'ai deux théories différentes et je me demande si l'une ou l'autre est fondée.

Théorie 1) Je réalise le recadrage en dessinant dans un contexte d'image hors écran de la taille de ma cible. Puisque je veux la partie centrale de l'image, j'ai défini l'argument CGRect passé à drawInRect sur une valeur plus grande que les limites du contexte de mon image. J'espérais que c'était cacher, mais est-ce que j'essaie plutôt de puiser dans une mémoire que je ne devrais pas toucher?

Théorie 2) Je fais tout cela dans un fil de fond. Je sais qu'il y a des portions d'UIKit qui sont limitées au fil principal. J'avais supposé/espéré que le passage à une vue hors écran ne faisait pas partie de celles-ci. Ai-je tort?

(Oh, comme je manque la méthode NSImage's drawInRect:fromRect:operation:fraction:.)

200
Jablair

Mise à jour du 28/05/14: J'ai écrit ceci lorsque iOS 3 ou plus était la nouvelle chose à la mode, je suis certain qu'il existe de meilleures façons de le faire maintenant, éventuellement intégrée. Comme beaucoup de personnes l'ont mentionné, cette méthode ne prend pas en compte la rotation; lisez quelques réponses supplémentaires et diffusez un peu d'amour positif pour que les réponses à cette question restent utiles à tous.

Réponse originale:

Je vais copier/coller ma réponse à la même question ailleurs:

Il n’existe pas de méthode de classe simple pour le faire, mais une fonction que vous pouvez utiliser pour obtenir les résultats souhaités: CGImageCreateWithImageInRect(CGImageRef, CGRect) vous aidera.

Voici un exemple court d'utilisation:

CGImageRef imageRef = CGImageCreateWithImageInRect([largeImage CGImage], cropRect);
// or use the UIImage wherever you like
[UIImageView setImage:[UIImage imageWithCGImage:imageRef]]; 
CGImageRelease(imageRef);
236
HitScan

Pour rogner des images de la rétine tout en conservant la même échelle et la même orientation, utilisez la méthode suivante dans une catégorie UIImage (iOS 4.0 et versions ultérieures):

- (UIImage *)crop:(CGRect)rect {
    if (self.scale > 1.0f) {
        rect = CGRectMake(rect.Origin.x * self.scale,
                          rect.Origin.y * self.scale,
                          rect.size.width * self.scale,
                          rect.size.height * self.scale);
    }

    CGImageRef imageRef = CGImageCreateWithImageInRect(self.CGImage, rect);
    UIImage *result = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];
    CGImageRelease(imageRef);
    return result;
}
88
Arne

Vous pouvez créer une catégorie UIImage et l’utiliser où vous le souhaitez. Basé sur la réponse HitScans et les commentaires ci-dessous. 

@implementation UIImage (Crop)

- (UIImage *)crop:(CGRect)rect {

    rect = CGRectMake(rect.Origin.x*self.scale, 
                      rect.Origin.y*self.scale, 
                      rect.size.width*self.scale, 
                      rect.size.height*self.scale);       

    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect);
    UIImage *result = [UIImage imageWithCGImage:imageRef 
                                          scale:self.scale 
                                    orientation:self.imageOrientation]; 
    CGImageRelease(imageRef);
    return result;
}

@end

Vous pouvez l'utiliser de cette façon:

UIImage *imageToCrop = <yourImageToCrop>;
CGRect cropRect = <areaYouWantToCrop>;   

//for example
//CGRectMake(0, 40, 320, 100);

UIImage *croppedImage = [imageToCrop crop:cropRect];
64
Vilém Kurz

Swift 3 version

func cropImage(imageToCrop:UIImage, toRect rect:CGRect) -> UIImage{

    let imageRef:CGImage = imageToCrop.cgImage!.cropping(to: rect)!
    let cropped:UIImage = UIImage(cgImage:imageRef)
    return cropped
}


let imageTop:UIImage  = UIImage(named:"one.jpg")! // add validation

enter image description here

avec l'aide de cette fonction de pont CGRectMake -> CGRect (crédits à cette réponse répondu par @rob mayoff):

 func CGRectMake(_ x: CGFloat, _ y: CGFloat, _ width: CGFloat, _ height: CGFloat) -> CGRect {
    return CGRect(x: x, y: y, width: width, height: height)
}

L'utilisation est:

if var image:UIImage  = UIImage(named:"one.jpg"){
   let  croppedImage = cropImage(imageToCrop: image, toRect: CGRectMake(
        image.size.width/4,
        0,
        image.size.width/2,
        image.size.height)
    )
}

Sortie:

enter image description here

49
Maxim Shoustin

Voici ma mise en œuvre de recadrage UIImage qui obéit à la propriété imageOrientation. Toutes les orientations ont été minutieusement testées.

inline double rad(double deg)
{
    return deg / 180.0 * M_PI;
}

UIImage* UIImageCrop(UIImage* img, CGRect rect)
{
    CGAffineTransform rectTransform;
    switch (img.imageOrientation)
    {
        case UIImageOrientationLeft:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -img.size.height);
            break;
        case UIImageOrientationRight:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -img.size.width, 0);
            break;
        case UIImageOrientationDown:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -img.size.width, -img.size.height);
            break;
        default:
            rectTransform = CGAffineTransformIdentity;
    };
    rectTransform = CGAffineTransformScale(rectTransform, img.scale, img.scale);

    CGImageRef imageRef = CGImageCreateWithImageInRect([img CGImage], CGRectApplyAffineTransform(rect, rectTransform));
    UIImage *result = [UIImage imageWithCGImage:imageRef scale:img.scale orientation:img.imageOrientation];
    CGImageRelease(imageRef);
    return result;
}
48
Sergii Rudchenko

Heads up: toutes ces réponses supposent un objet image CGImage- backed.

image.CGImage peut renvoyer nil, si la UIImage est appuyée par une CIImage, ce qui serait le cas si vous créiez cette image avec une CIFilter

Dans ce cas, vous devrez peut-être dessiner l'image dans un nouveau contexte et renvoyer cette image ( slow ).

UIImage* crop(UIImage *image, rect) {
    UIGraphicsBeginImageContextWithOptions(rect.size, false, [image scale]);
    [image drawAtPoint:CGPointMake(-rect.Origin.x, -rect.Origin.y)];
    cropped_image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return cropped_image;
}
38
colinta

Aucune des réponses ici ne gère correctement tous les problèmes d’échelle et de rotation. Voici une synthèse de tout ce qui a été dit jusqu'à présent, à jour depuis iOS7/8. Il est censé être inclus en tant que méthode dans une catégorie sur UIImage.

- (UIImage *)croppedImageInRect:(CGRect)rect
{
    double (^rad)(double) = ^(double deg) {
        return deg / 180.0 * M_PI;
    };

    CGAffineTransform rectTransform;
    switch (self.imageOrientation) {
        case UIImageOrientationLeft:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -self.size.height);
            break;
        case UIImageOrientationRight:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -self.size.width, 0);
            break;
        case UIImageOrientationDown:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -self.size.width, -self.size.height);
            break;
        default:
            rectTransform = CGAffineTransformIdentity;
    };
    rectTransform = CGAffineTransformScale(rectTransform, self.scale, self.scale);

    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], CGRectApplyAffineTransform(rect, rectTransform));
    UIImage *result = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];
    CGImageRelease(imageRef);

    return result;
}
32
awolf
CGSize size = [originalImage size];
int padding = 20;
int pictureSize = 300;
int startCroppingPosition = 100;
if (size.height > size.width) {
    pictureSize = size.width - (2.0 * padding);
    startCroppingPosition = (size.height - pictureSize) / 2.0; 
} else {
    pictureSize = size.height - (2.0 * padding);
    startCroppingPosition = (size.width - pictureSize) / 2.0;
}
// WTF: Don't forget that the CGImageCreateWithImageInRect believes that 
// the image is 180 rotated, so x and y are inverted, same for height and width.
CGRect cropRect = CGRectMake(startCroppingPosition, padding, pictureSize, pictureSize);
CGImageRef imageRef = CGImageCreateWithImageInRect([originalImage CGImage], cropRect);
UIImage *newImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:originalImage.imageOrientation];
[m_photoView setImage:newImage];
CGImageRelease(imageRef);

La plupart des réponses que j'ai vues concernent uniquement une position de (0, 0) pour (x, y). Ok C'est un cas, mais j'aimerais que mon opération de recadrage soit centrée. Ce qui m'a pris un certain temps à comprendre, c'est la ligne qui suit le commentaire de la WTF.

Prenons le cas d'une image capturée avec une orientation portrait:

  1. La hauteur de l'image d'origine est supérieure à sa largeur (Woo, pas de surprise pour l'instant!)
  2. L'image que la méthode CGImageCreateWithImageInRect imagine dans son propre monde n'est pas vraiment un portrait, mais un paysage (c'est aussi pourquoi, si vous n'utilisez pas l'argument d'orientation dans le constructeur imageWithCGImage, il apparaîtra avec une rotation de 180).
  3. Donc, vous devriez imaginer que c'est un paysage, la position (0, 0) étant le coin en haut à droite de l'image. 

J'espère que cela a du sens! Si ce n'est pas le cas, essayez différentes valeurs et vous verrez que la logique est inversée lorsqu'il s'agit de choisir les bons paramètres x, y, largeur et hauteur pour votre cropRect.

10
Jordan

Extension rapide

extension UIImage {
    func crop(var rect: CGRect) -> UIImage {
        rect.Origin.x*=self.scale
        rect.Origin.y*=self.scale
        rect.size.width*=self.scale
        rect.size.height*=self.scale

        let imageRef = CGImageCreateWithImageInRect(self.CGImage, rect)
        let image = UIImage(CGImage: imageRef, scale: self.scale, orientation: self.imageOrientation)!
        return image
    }
}
7
Epic Byte

Swift3

extension UIImage {
    func crop(rect: CGRect) -> UIImage? {
        var scaledRect = rect
        scaledRect.Origin.x *= scale
        scaledRect.Origin.y *= scale
        scaledRect.size.width *= scale
        scaledRect.size.height *= scale
        guard let imageRef: CGImage = cgImage?.cropping(to: scaledRect) else {
            return nil
        }
        return UIImage(cgImage: imageRef, scale: scale, orientation: imageOrientation)
    }
}
7
neoneye

Version rapide de la réponse de awolf, qui a fonctionné pour moi:

public extension UIImage {
    func croppedImage(inRect rect: CGRect) -> UIImage {
        let rad: (Double) -> CGFloat = { deg in
            return CGFloat(deg / 180.0 * .pi)
        }
        var rectTransform: CGAffineTransform
        switch imageOrientation {
        case .left:
            let rotation = CGAffineTransform(rotationAngle: rad(90))
            rectTransform = rotation.translatedBy(x: 0, y: -size.height)
        case .right:
            let rotation = CGAffineTransform(rotationAngle: rad(-90))
            rectTransform = rotation.translatedBy(x: -size.width, y: 0)
        case .down:
            let rotation = CGAffineTransform(rotationAngle: rad(-180))
            rectTransform = rotation.translatedBy(x: -size.width, y: -size.height)
        default:
            rectTransform = .identity
        }
        rectTransform = rectTransform.scaledBy(x: scale, y: scale)
        let transformedRect = rect.applying(rectTransform)
        let imageRef = cgImage!.cropping(to: transformedRect)!
        let result = UIImage(cgImage: imageRef, scale: scale, orientation: imageOrientation)
        return result
    }
}
5
Mark Leonard

Meilleure solution pour recadrer un UIImage dans Swift, en terme de précision, de mise à l'échelle des pixels ...:

private func squareCropImageToSideLength(let sourceImage: UIImage,
    let sideLength: CGFloat) -> UIImage {
        // input size comes from image
        let inputSize: CGSize = sourceImage.size

        // round up side length to avoid fractional output size
        let sideLength: CGFloat = ceil(sideLength)

        // output size has sideLength for both dimensions
        let outputSize: CGSize = CGSizeMake(sideLength, sideLength)

        // calculate scale so that smaller dimension fits sideLength
        let scale: CGFloat = max(sideLength / inputSize.width,
            sideLength / inputSize.height)

        // scaling the image with this scale results in this output size
        let scaledInputSize: CGSize = CGSizeMake(inputSize.width * scale,
            inputSize.height * scale)

        // determine point in center of "canvas"
        let center: CGPoint = CGPointMake(outputSize.width/2.0,
            outputSize.height/2.0)

        // calculate drawing rect relative to output Size
        let outputRect: CGRect = CGRectMake(center.x - scaledInputSize.width/2.0,
            center.y - scaledInputSize.height/2.0,
            scaledInputSize.width,
            scaledInputSize.height)

        // begin a new bitmap context, scale 0 takes display scale
        UIGraphicsBeginImageContextWithOptions(outputSize, true, 0)

        // optional: set the interpolation quality.
        // For this you need to grab the underlying CGContext
        let ctx: CGContextRef = UIGraphicsGetCurrentContext()
        CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh)

        // draw the source image into the calculated rect
        sourceImage.drawInRect(outputRect)

        // create new image from bitmap context
        let outImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()

        // clean up
        UIGraphicsEndImageContext()

        // pass back new image
        return outImage
}

Instructions utilisées pour appeler cette fonction:

let image: UIImage = UIImage(named: "Image.jpg")!
let squareImage: UIImage = self.squareCropImageToSideLength(image, sideLength: 320)
self.myUIImageView.image = squareImage

Remarque: l'inspiration initiale du code source écrite en Objective-C a été trouvée sur le blog "Cocoanetics".

4
King-Wizard

Cela semble un peu étrange mais fonctionne très bien et prend en compte l'orientation de l'image:

var image:UIImage = ...

let img = CIImage(image: image)!.imageByCroppingToRect(rect)
image = UIImage(CIImage: img, scale: 1, orientation: image.imageOrientation)
2
MuniekMg
- (UIImage *)getSubImage:(CGRect) rect{
    CGImageRef subImageRef = CGImageCreateWithImageInRect(self.CGImage, rect);
    CGRect smallBounds = CGRectMake(rect.Origin.x, rect.Origin.y, CGImageGetWidth(subImageRef), CGImageGetHeight(subImageRef));

    UIGraphicsBeginImageContext(smallBounds.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawImage(context, smallBounds, subImageRef);
    UIImage* smallImg = [UIImage imageWithCGImage:subImageRef];
    UIGraphicsEndImageContext();

    return smallImg;
}
1
Golden

Voici une version mise à jour de Swift 3 basée sur Noodles answer

func cropping(to rect: CGRect) -> UIImage? {

    if let cgCrop = cgImage?.cropping(to: rect) {
        return UIImage(cgImage: cgCrop)
    }
    else if let ciCrop = ciImage?.cropping(to: rect) {
        return UIImage(ciImage: ciCrop)
    }

    return nil
}
1
voidref

Sur iOS9.2SDK, j’utilise la méthode ci-dessous pour convertir une image de UIView à UIImage. 

-(UIImage *)getNeedImageFrom:(UIImage*)image cropRect:(CGRect)rect
{
  CGSize cropSize = rect.size;
  CGFloat widthScale = image.size.width/self.imageViewOriginal.bounds.size.width;
  CGFloat heightScale = image.size.height/self.imageViewOriginal.bounds.size.height;
  cropSize = CGSizeMake(rect.size.width*widthScale, 
              rect.size.height*heightScale);
  CGPoint pointCrop = CGPointMake(rect.Origin.x*widthScale,
             rect.Origin.y*heightScale);
  rect = CGRectMake(pointCrop.x, pointCrop.y, cropSize.width, cropSize.height);
  CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, rect);
  UIImage *croppedImage = [UIImage imageWithCGImage:subImage];
  CGImageRelease(subImage);

  return croppedImage;
}
1
user5176302
 (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;
}
1
Bhushan_pawar

Swift 2.0 Update (compatibilité CIImage)

Développer en dehors de Maxim's Answer mais fonctionne si votre image est aussi basée sur CIImage.

public extension UIImage {
    func imageByCroppingToRect(rect: CGRect) -> UIImage? {
        if let image = CGImageCreateWithImageInRect(self.CGImage, rect) {
            return UIImage(CGImage: image)
        } else if let image = (self.CIImage)?.imageByCroppingToRect(rect) {
            return UIImage(CIImage: image)
        }
       return nil
   }
}
1
NoodleOfDeath

Suivre la réponse de @Arne . I Fixant simplement la fonction de catégorie. mettez-le dans la catégorie de UIImage.

-(UIImage*)cropImage:(CGRect)rect{

    UIGraphicsBeginImageContextWithOptions(rect.size, false, [self scale]);
    [self drawAtPoint:CGPointMake(-rect.Origin.x, -rect.Origin.y)];
    UIImage* cropped_image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return cropped_image;
}
0
Linh Nguyen

J'utilise la méthode ci-dessous.

  -(UIImage *)getNeedImageFrom:(UIImage*)image cropRect:(CGRect)rect
  {
    CGSize cropSize = rect.size;
    CGFloat widthScale =  
    image.size.width/self.imageViewOriginal.bounds.size.width;
    CGFloat heightScale = 
    image.size.height/self.imageViewOriginal.bounds.size.height;
    cropSize = CGSizeMake(rect.size.width*widthScale,  
    rect.size.height*heightScale);
    CGPoint  pointCrop = CGPointMake(rect.Origin.x*widthScale, 
    rect.Origin.y*heightScale);
    rect = CGRectMake(pointCrop.x, pointCrop.y, cropSize.width, 
    cropSize.height);
    CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, rect);
    UIImage *croppedImage = [UIImage imageWithCGImage:subImage];
    CGImageRelease(subImage);
    return croppedImage;

}

0
user5176302

Swift 5:

extension UIImage {
    func cropped(rect: CGRect) -> UIImage? {
        guard let cgImage = cgImage else { return nil }

        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
        let context = UIGraphicsGetCurrentContext()

        context?.translateBy(x: 0.0, y: self.size.height)
        context?.scaleBy(x: 1.0, y: -1.0)
        context?.draw(cgImage, in: CGRect(x: rect.minX, y: rect.minY, width: self.size.width, height: self.size.height), byTiling: false)


        let croppedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return croppedImage
    }
}
0
huync

Regardez https://github.com/vvbogdan/BVCropPhoto

- (UIImage *) croppedImage {
 CGFloat scale = self.sourceImage.size.width/self.scrollView.contentSize.width; 

 UIImage * finalImage = nil; 
 CGRect targetFrame = CGRectMake ((self.scrollView.contentInset.left + self.scrollView.contentOffset.x) * scale, 
 (Self.scrollView.contentInset.top + self.scrollView.contentOffset.y) * scale, .__ self.cropSize.width * scale, 
 self.cropSize.height * scale); 

 CGImageRef contextImage = CGImageCreateWithImageInRect ([[self imageWithRotation: self.sourceImage] CGImage], targetFrame); 

 if (contextImage! = NULL) {
 finalImage = [UIImage imageWithCGImage: contextImage 
 scale: self.sourceImage.scale 
 orientation: UIImageOrientationUp]; 

 CGImageRelease (contextImage); 
 } 

 return finalImage; 
} 


- (UIImage *) imageWithRotation: (UIImage *) image {


 if (image.imageOrientation == UIImageOrientationUp) renvoie l'image; 
 CGAffineTransform transform = CGAffineTransformIdentity; 

 commutateur (image.imageOrientation) {
 case UIImageOrientationDown: 
 case UIImageOrientationDownMirrored: 
 transform = CGAffineTransformTranslate (transform, image.size.width, image.size.height); 
 transform = CGAffineTransformRotate (transform, M_PI); 
 Pause;

 case UIImageOrientationLeft: 
 case UIImageOrientationLeftMirrored: 
 transform = CGAffineTransformTranslate (transform, image.size.width, 0); 
 transform = CGAffineTransformRotate (transform, M_PI_2); 
 Pause;

 case UIImageOrientationRight: 
 case UIImageOrientationRightMirrored: 
 transform = CGAffineTransformTranslate (transform, 0, image.size.height); 
 transform = CGAffineTransformRotate (transform, -M_PI_2); 
 Pause;
 case UIImageOrientationUp: 
 case UIImageOrientationUpMirrored: 
 Pause;
 } 

 commutateur (image.imageOrientation) {
 case UIImageOrientationUpMirrored: 
 case UIImageOrientationDownMirrored: 
 transform = CGAffineTransformTranslate (transform, image.size.width, 0); 
 transform = CGAffineTransformScale (transform, -1, 1); 
 Pause;

 case UIImageOrientationLeftMirrored: 
 case UIImageOrientationRightMirrored: 
 transform = CGAffineTransformTranslate (transform, image.size.height, 0); 
 transform = CGAffineTransformScale (transform, -1, 1); 
 Pause;
 case UIImageOrientationUp: 
 case UIImageOrientationDown: 
 case UIImageOrientationLeft: 
 case UIImageOrientationRight: 
 Pause;
 } 

 // Maintenant, nous dessinons l'image CGImage sous-jacente dans un nouveau contexte, en appliquant la transformation 
 // calculé ci-dessus .
 CGContextRef ctx = CGBitmapContextCreate (NULL, image.size.width, image.size.height, 
 CGImageGetBitsPerComponent (image.CGImage), 0, 
 CGImageGetColorSpace (image.CGImage), 
 ); 
 CGContextConcatCTM (ctx, transform); 
 commutateur (image.imageOrientation) {
 case UIImageOrientationLeft: 
 case UIImageOrientationLeftMirrored: 
 case UIImageOrientationRight: 
 case UIImageOrientationRightMirrored: 
 // Grr ...
 CGContextDrawImage (ctx, CGRectMake (0, 0, image.size.height, image.size.width), image.CGImage); 
 Pause;

 défaut:
 CGContextDrawImage (ctx, CGRectMake (0, 0, image.size.width, image.size.height), image.CGImage); 
 Pause;
 } 

 // Et maintenant, nous venons de créer une nouvelle UIImage à partir du contexte de dessin 
 CGImageRef cgimg = CGBitmapContextCreateImage (ctx); 
 UIImage * img = [UIImage imageWithCGImage: cgimg]; 
 CGContextRelease (ctx); 
 CGImageRelease (cgimg); 
 return img; 

} 
0
Nowytech

L'extrait de code ci-dessous peut aider.

import UIKit

extension UIImage {
    func cropImage(toRect rect: CGRect) -> UIImage? {
        if let imageRef = self.cgImage?.cropping(to: rect) {
            return UIImage(cgImage: imageRef)
        }
        return nil
    }
}
0
luhuiya

Je n'étais pas satisfait des autres solutions car elles prenaient plusieurs fois (consommant plus d'énergie que nécessaire) ou rencontraient des problèmes d'orientation. Voici ce que j'ai utilisé pour une image carrée redimensionnée à partir d'une image UIImage *.

CGFloat minimumSide = fminf(image.size.width, image.size.height);
CGFloat finalSquareSize = 600.;

//create new drawing context for right size
CGRect rect = CGRectMake(0, 0, finalSquareSize, finalSquareSize);
CGFloat scalingRatio = 640.0/minimumSide;
UIGraphicsBeginImageContext(rect.size);

//draw
[image drawInRect:CGRectMake((minimumSide - photo.size.width)*scalingRatio/2., (minimumSide - photo.size.height)*scalingRatio/2., photo.size.width*scalingRatio, photo.size.height*scalingRatio)];

UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();
0
Matthieu Rouif