it-swarm.com.de

Einen UIImage zuschneiden

Ich habe einen Code, der die Größe eines Bildes ändert, sodass ich ein skaliertes Stück der Bildmitte erhalten kann. Ich benutze dies, um einen UIImage zu nehmen und eine kleine quadratische Darstellung eines Bildes zurückzugeben, ähnlich wie in der Albumansicht der Fotos app. (Ich weiß, ich könnte UIImageView verwenden und den Zuschneidemodus anpassen, um dieselben Ergebnisse zu erzielen, aber diese Bilder werden manchmal in UIWebViews angezeigt).

Ich habe einige Abstürze in diesem Code bemerkt und bin etwas ratlos. Ich habe zwei verschiedene Theorien und ich frage mich, ob eine der beiden Grundlagen ist.

Theorie 1) Den Zuschnitt erreiche ich durch Zeichnen in einen Offscreen-Bildkontext meiner Zielgröße. Da ich den mittleren Teil des Bildes haben möchte, setze ich das CGRect-Argument, das an drawInRect übergeben wird, auf etwas, das größer ist als die Grenzen meines Bildkontexts. Ich hatte gehofft, dass dies koscher war, aber versuche ich stattdessen, andere Erinnerungen zu überzeichnen, die ich nicht berühren sollte?

Theorie 2) Ich mache das alles in einem Hintergrund-Thread. Ich weiß, dass es Teile von UIKit gibt, die auf den Haupt-Thread beschränkt sind. Ich nahm an, ich hoffe, dass das Zeichnen in eine Offscreen-Ansicht nicht dazu gehört. Liege ich falsch?

(Oh, wie ich NSImage's drawInRect:fromRect:operation:fraction: Methode vermisse.)

200
Jablair

Update 2014-05-28: Ich habe dies geschrieben, als iOS 3 oder so die heiße neue Sache war. Wie viele Leute erwähnt haben, berücksichtigt diese Methode die Rotation nicht. Lesen Sie einige zusätzliche Antworten und verbreiten Sie einige positive Erfahrungen, um die Antworten auf diese Frage für alle hilfreich zu halten.

Ursprüngliche Antwort:

Ich werde meine Antwort auf dieselbe Frage an anderer Stelle kopieren/einfügen:

Es gibt keine einfache Klassenmethode dafür, aber es gibt eine Funktion, mit der Sie die gewünschten Ergebnisse erzielen können: CGImageCreateWithImageInRect(CGImageRef, CGRect) wird Ihnen helfen.

Hier ein kurzes Beispiel:

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

Verwenden Sie die folgende Methode in einer UIImage-Kategorie (iOS 4.0 und höher), um Retina-Bilder bei gleichem Maßstab und gleicher Ausrichtung zuzuschneiden:

- (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

Sie können eine UIImage-Kategorie erstellen und sie überall verwenden, wo Sie sie benötigen. Basierend auf der Antwort und den Kommentaren von HitScans. 

@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

Sie können es so verwenden:

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

mit Hilfe dieser Bridge-Funktion CGRectMake -> CGRect (Credits an diese Antwort beantwortet von @rob mayoff):

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

Die Verwendung ist:

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)
    )
}

Ausgabe:

enter image description here

49
Maxim Shoustin

Hier ist meine UIImage-Crop-Implementierung, die der imageOrientation-Eigenschaft folgt. Alle Orientierungen wurden gründlich getestet.

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

Heads up: Alle diese Antworten setzen ein CGImage- gestütztes Bildobjekt voraus.

image.CGImage kann null zurückgeben, wenn die UIImage von einer CIImage unterstützt wird. Dies wäre der Fall, wenn Sie dieses Bild mit einer CIFilter erstellen. 

In diesem Fall müssen Sie möglicherweise das Bild in einem neuen Kontext zeichnen und dieses Bild zurückgeben ( 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

Keine der Antworten hier behandelt alle Skalen- und Rotationsprobleme zu 100% korrekt. Hier ist eine Synthese aus allem, was bisher gesagt wurde, ab iOS7/8. Es soll als eine Methode in einer Kategorie auf UIImage enthalten sein.

- (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);

Die meisten Antworten, die ich gesehen habe, befassen sich nur mit einer Position (0, 0) für (x, y). Ok Das ist ein Fall, aber ich würde mir wünschen, dass meine Beschneidungsoperation zentriert wird. Was mich eine Weile brauchte, um herauszufinden, ist die Zeile nach dem WTF-Kommentar.

Nehmen wir den Fall eines Bildes, das im Hochformat aufgenommen wurde:

  1. Die ursprüngliche Bildhöhe ist höher als die Breite (Woo, bisher keine Überraschung!)
  2. Das Bild, das die CGImageCreateWithImageInRect-Methode in ihrer eigenen Welt vorstellt, ist zwar nicht wirklich ein Porträt, sondern eine Landschaft (wenn Sie also nicht das Ausrichtungsargument im imageWithCGImage-Konstruktor verwenden, wird es als 180-Drehung angezeigt).
  3. Man sollte sich also vorstellen, dass es sich um eine Landschaft handelt, wobei die Position (0, 0) die obere rechte Ecke des Bildes ist. 

Hoffe es macht Sinn! Wenn dies nicht der Fall ist, versuchen Sie es mit anderen Werten. Sie werden feststellen, dass die Logik invertiert ist, wenn Sie das richtige X, Y, Breite und Höhe für cropRect auswählen.

10
Jordan

Schnelle Erweiterung

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

Schnelle Version von awolfs Antwort, die für mich funktioniert hat:

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

Beste Lösung für das Beschneiden eines UIImage in Swift, hinsichtlich der Genauigkeit, der Pixel-Skalierung ...:

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
}

Anweisungen zum Aufrufen dieser Funktion:

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

Hinweis: Der erste Quellcode, der in Objective-C geschrieben wurde, wurde im Blog "Cocoanetics" gefunden.

4
King-Wizard

Sieht ein bisschen seltsam aus, funktioniert aber gut und berücksichtigt die Ausrichtung des Bildes:

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

Hier ist eine aktualisierte Version von Swift 3 basierend auf 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

Unter iOS9.2SDK verwende ich die Methode unten, um ein Bild von UIView in UIImage zu konvertieren 

-(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 (CIImage-Kompatibilität)

Erweiterung von Maxim's Answer , funktioniert aber auch, wenn Ihr Bild CIImage basiert.

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

Folgen Sie der Antwort von @Arne . Setze es in die Kategorie 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

Ich verwende die Methode unten.

  -(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

Siehe 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 
 Orientierung: UIImageOrientationUp]; 

 CGImageRelease (contextImage); 
 } 

 return finalImage; 
} 


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


 if (image.imageOrientation == UIImageOrientationUp) gibt das Image zurück. CGAffineTransform-Transformation = CGAffineTransformIdentity; 

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

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

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

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

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

 // Jetzt zeichnen wir das zugrunde liegende CGImage in einen neuen Kontext und wenden die Transformation an 
 // oben berechnet .
 CGContextRef ctx = CGBitmapContextCreate (NULL, image.size.width, image.size.height, 
 CGImageGetBitsPerComponent (image.CGImage), 0, 
 CGImageGetColorSpace (image.CGImage), 
 ); 
 CGContextConcatCTM (ctx, transform); 
 switch (image.imageOrientation) {
 case UIImageOrientationLeft: 
 case UIImageOrientationLeftMirrored: 
 case UIImageOrientationRight: 
 case UIImageOrientationRightMirrored: 
 // Grr ...
 CGContextDrawImage (ctx, CGRectMake (0, 0, image.size.height, image.size.width), image.CGImage); 
 brechen;

 Standard:
 CGContextDrawImage (ctx, CGRectMake (0, 0, image.size.width, image.size.height), image.CGImage); 
 brechen;
 } 

 // Und jetzt erstellen wir einfach einen neuen UIImage aus dem Zeichnungskontext 
 CGImageRef cgimg = CGBitmapContextCreateImage (ctx); 
 UIImage * img = [UIImage imageWithCGImage: cgimg]; 
 CGContextRelease (ctx); 
 CGImageRelease (cgimg); 
 return img; 

} 
0
Nowytech

Das folgende Code-Snippet kann hilfreich sein.

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

Ich war mit anderen Lösungen nicht zufrieden, weil sie entweder mehrmals beanspruchen (mehr Energie als nötig benötigt) oder Orientierungsprobleme haben. Folgendes habe ich für ein skaliertes quadratisches beschnittenes Bild aus einem UIImage * -Bild verwendet.

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