UIImage: Größe ändern, dann Zuschneiden


187

Ich habe mein Gesicht buchstäblich seit Tagen in dieses geschlagen und obwohl ich ständig das Gefühl habe, am Rande der Offenbarung zu stehen, kann ich mein Ziel einfach nicht erreichen.

Ich dachte im Voraus in den konzeptionellen Phasen meines Entwurfs, dass es eine triviale Angelegenheit wäre, ein Bild von der Kamera oder Bibliothek des iPhones aufzunehmen und es mit einer Funktion, die der Option „ Seitenfüllung “ von entspricht, auf eine bestimmte Höhe zu verkleinern UIImageView (vollständig im Code) und dann alles abschneiden , was nicht in ein übergebenes CGRect passt.

Das Originalbild von der Kamera oder Bibliothek zu erhalten, war trivial. Ich bin schockiert darüber, wie schwierig sich die beiden anderen Schritte erwiesen haben.

Das beigefügte Bild zeigt, was ich erreichen möchte. Wäre jemand bitte so freundlich, meine Hand zu halten? Jedes Codebeispiel, das ich bisher gefunden habe, scheint das Bild zu zerschlagen, auf dem Kopf zu stehen, wie Mist auszusehen, außerhalb der Grenzen zu zeichnen oder auf andere Weise einfach nicht richtig zu funktionieren.


7
Der Link zu Ihrem Bild ist unterbrochen.

1
Eine Sache, die uns nicht schockiert, ist, warum Apple sie nicht zu UIImagePickerController hinzugefügt hat - es ist verdammt schwierig ;-)
Tim

Antworten:


246

Ich brauchte dasselbe - in meinem Fall, um die Dimension auszuwählen, die nach der Skalierung passt, und dann jedes Ende zuzuschneiden, um den Rest an die Breite anzupassen. (Ich arbeite im Querformat und habe daher möglicherweise keine Mängel im Hochformat festgestellt.) Hier ist mein Code - er ist Teil einer Kategorie auf UIImage. Die Zielgröße in meinem Code ist immer auf die Vollbildgröße des Geräts eingestellt.

@implementation UIImage (Extras)

#pragma mark -
#pragma mark Scale and crop image

- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
{
    UIImage *sourceImage = self;
    UIImage *newImage = nil;    
    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;
    CGFloat targetWidth = targetSize.width;
    CGFloat targetHeight = targetSize.height;
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;
    CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

    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;

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

    UIGraphicsBeginImageContext(targetSize); // this will crop

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

    //pop the context to get back to the default
    UIGraphicsEndImageContext();

    return newImage;
}

1
Seltsamerweise funktioniert es im Simulator, aber auf dem Gerät erhalte ich den ExecBadAccess.
Sorin Antohi

5
Das Problem mit der fehlerhaften Ausführung tritt auf, weil die UIImage-Funktionen nicht threadsicher sind. Deshalb stürzt es manchmal ab, manchmal nicht
Erik

1
Dieser Code hat bei mir gut funktioniert, aber auf der Netzhaut war er verschwommen. Die Kombination dieses Codes mit dem Kommentar unten machte alles perfekt: stackoverflow.com/questions/603907/…
MaxGabriel

23
Verwenden Sie UIGraphicsBeginImageContextWithOptions (targetSize, YES, 0.0); um das Bild auch auf der Netzhaut schön zu machen.
Borut Tomazin

1
Dies funktioniert bei mir im Hochformat, aber nicht im Querformat. Die Höhe ist in Landschaft gestreckt. Irgendeine Idee warum?
Darren

77

Ein älterer Beitrag enthält Code für eine Methode zum Ändern der Größe Ihres UIImage. Der relevante Teil ist wie folgt:

+ (UIImage*)imageWithImage:(UIImage*)image 
               scaledToSize:(CGSize)newSize;
{
   UIGraphicsBeginImageContext( newSize );
   [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
   UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();

   return newImage;
}

Was das Zuschneiden betrifft, sollte das resultierende Bild, wenn Sie die Methode so ändern, dass für die Skalierung eine andere Größe als für den Kontext verwendet wird, an die Grenzen des Kontexts gekürzt werden.


3
Macht keinen Sinn, warum dies die Bildausrichtung korrigiert, aber es tut es und somit hat es mein Problem behoben, dass die Kamera nicht die richtige Ausrichtung in der zurückgibt originalImage. Vielen Dank.
Brenden

10
Ich stellte fest, dass die Größenänderung eines Bildes auf einem Netzhautgerät verschwommen erschien. Um die Übersichtlichkeit zu gewährleisten, habe ich die erste Zeile wie folgt geändert : UIGraphicsBeginImageContextWithOptions(newSize, 1.0f, 0.0f);. (hier erklärt: stackoverflow.com/questions/4334233/… )
Johngraham

Es dreht das Bild - schneidet es aber nicht richtig zu! Warum hat es so viele Stimmen?
Dejell

18
+ (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)targetSize {
    //If scaleFactor is not touched, no scaling will occur      
    CGFloat scaleFactor = 1.0;

    //Deciding which factor to use to scale the image (factor = targetSize / imageSize)
    if (image.size.width > targetSize.width || image.size.height > targetSize.height)
        if (!((scaleFactor = (targetSize.width / image.size.width)) > (targetSize.height / image.size.height))) //scale to fit width, or
            scaleFactor = targetSize.height / image.size.height; // scale to fit heigth.

    UIGraphicsBeginImageContext(targetSize); 

    //Creating the rect where the scaled image is drawn in
    CGRect rect = CGRectMake((targetSize.width - image.size.width * scaleFactor) / 2,
                             (targetSize.height -  image.size.height * scaleFactor) / 2,
                             image.size.width * scaleFactor, image.size.height * scaleFactor);

    //Draw the image into the rect
    [image drawInRect:rect];

    //Saving the image, ending image context
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return scaledImage;
}

Ich schlage diesen vor. Ist sie nicht eine Schönheit? ;)


1
Dieser ist gut, wenn Sie zuerst die if-Anweisung entfernen, die als AspectFill fungiert.
RaffAl


7

Bitte schön. Dieser ist perfekt ;-)

BEARBEITEN: siehe unten Kommentar - "Funktioniert nicht mit bestimmten Bildern, schlägt fehl mit: CGContextSetInterpolationQuality: ungültiger Kontext 0x0 Fehler"

// Resizes the image according to the given content mode, taking into account the image's orientation
- (UIImage *)resizedImageWithContentMode:(UIViewContentMode)contentMode imageToScale:(UIImage*)imageToScale bounds:(CGSize)bounds interpolationQuality:(CGInterpolationQuality)quality {
    //Get the size we want to scale it to
    CGFloat horizontalRatio = bounds.width / imageToScale.size.width;
    CGFloat verticalRatio = bounds.height / imageToScale.size.height;
    CGFloat ratio;

    switch (contentMode) {
        case UIViewContentModeScaleAspectFill:
            ratio = MAX(horizontalRatio, verticalRatio);
            break;

        case UIViewContentModeScaleAspectFit:
            ratio = MIN(horizontalRatio, verticalRatio);
            break;

        default:
            [NSException raise:NSInvalidArgumentException format:@"Unsupported content mode: %d", contentMode];
    }

    //...and here it is
    CGSize newSize = CGSizeMake(imageToScale.size.width * ratio, imageToScale.size.height * ratio);


    //start scaling it
    CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
    CGImageRef imageRef = imageToScale.CGImage;
    CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                                newRect.size.width,
                                                newRect.size.height,
                                                CGImageGetBitsPerComponent(imageRef),
                                                0,
                                                CGImageGetColorSpace(imageRef),
                                                CGImageGetBitmapInfo(imageRef));

    CGContextSetInterpolationQuality(bitmap, quality);

    // Draw into the context; this scales the image
    CGContextDrawImage(bitmap, newRect, imageRef);

    // Get the resized image from the context and a UIImage
    CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];

    // Clean up
    CGContextRelease(bitmap);
    CGImageRelease(newImageRef);

    return newImage;
}

1
Sieh wirklich wunderschön aus :) Ich mag InterpolationQuality hier
Kostiantyn Sokolinskyi

Funktioniert nicht mit bestimmten Bildern, schlägt fehl mit: CGContextSetInterpolationQuality: ungültiger Kontext 0x0 Fehler
RaffAl

6

Dies ist eine Version der Antwort von Jane Sales in Swift. Prost!

public func resizeImage(image: UIImage, size: CGSize) -> UIImage? {
    var returnImage: UIImage?

    var scaleFactor: CGFloat = 1.0
    var scaledWidth = size.width
    var scaledHeight = size.height
    var thumbnailPoint = CGPointMake(0, 0)

    if !CGSizeEqualToSize(image.size, size) {
        let widthFactor = size.width / image.size.width
        let heightFactor = size.height / image.size.height

        if widthFactor > heightFactor {
            scaleFactor = widthFactor
        } else {
            scaleFactor = heightFactor
        }

        scaledWidth = image.size.width * scaleFactor
        scaledHeight = image.size.height * scaleFactor

        if widthFactor > heightFactor {
            thumbnailPoint.y = (size.height - scaledHeight) * 0.5
        } else if widthFactor < heightFactor {
            thumbnailPoint.x = (size.width - scaledWidth) * 0.5
        }
    }

    UIGraphicsBeginImageContextWithOptions(size, true, 0)

    var thumbnailRect = CGRectZero
    thumbnailRect.origin = thumbnailPoint
    thumbnailRect.size.width = scaledWidth
    thumbnailRect.size.height = scaledHeight

    image.drawInRect(thumbnailRect)
    returnImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    return returnImage
}

2

Ich habe Brad Larsons Code geändert. Es wird das Bild in einem bestimmten Rechteck füllen.

-(UIImage*) scaleAndCropToSize:(CGSize)newSize;
{
    float ratio = self.size.width / self.size.height;

    UIGraphicsBeginImageContext(newSize);

    if (ratio > 1) {
        CGFloat newWidth = ratio * newSize.width;
        CGFloat newHeight = newSize.height;
        CGFloat leftMargin = (newWidth - newHeight) / 2;
        [self drawInRect:CGRectMake(-leftMargin, 0, newWidth, newHeight)];
    }
    else {
        CGFloat newWidth = newSize.width;
        CGFloat newHeight = newSize.height / ratio;
        CGFloat topMargin = (newHeight - newWidth) / 2;
        [self drawInRect:CGRectMake(0, -topMargin, newSize.width, newSize.height/ratio)];
    }

    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

1
Getestet mit zwei anderen Bildern, Hoch- und Querformat. Dies führt NICHT die Aspektfüllung durch.
RaffAl

2

Die Xamarin.iOS-Version für akzeptierte Antworten zum Ändern der Größe und anschließenden Zuschneiden von UIImage (Aspect Fill) finden Sie unten

    public static UIImage ScaleAndCropImage(UIImage sourceImage, SizeF targetSize)
    {
        var imageSize = sourceImage.Size;
        UIImage newImage = null;
        var width = imageSize.Width;
        var height = imageSize.Height;
        var targetWidth = targetSize.Width;
        var targetHeight = targetSize.Height;
        var scaleFactor = 0.0f;
        var scaledWidth = targetWidth;
        var scaledHeight = targetHeight;
        var thumbnailPoint = PointF.Empty;
        if (imageSize != targetSize)
        {
            var widthFactor = targetWidth / width;
            var 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;
            // center the image
            if (widthFactor > heightFactor)
            {
                thumbnailPoint.Y = (targetHeight - scaledHeight) * 0.5f;
            }
            else
            {
                if (widthFactor < heightFactor)
                {
                    thumbnailPoint.X = (targetWidth - scaledWidth) * 0.5f;
                }
            }
        }
        UIGraphics.BeginImageContextWithOptions(targetSize, false, 0.0f);
        var thumbnailRect = new RectangleF(thumbnailPoint, new SizeF(scaledWidth, scaledHeight));
        sourceImage.Draw(thumbnailRect);
        newImage = UIGraphics.GetImageFromCurrentImageContext();
        if (newImage == null)
        {
            Console.WriteLine("could not scale image");
        }
        //pop the context to get back to the default
        UIGraphics.EndImageContext();

        return newImage;
    }

2

Ich habe Sam Wirchs Leitfaden auf schnell umgestellt und es hat gut für mich funktioniert, obwohl das endgültige Bild ein leichtes "Quetschen" enthält, das ich nicht lösen konnte.

func resizedCroppedImage(image: UIImage, newSize:CGSize) -> UIImage {
    var ratio: CGFloat = 0
    var delta: CGFloat = 0
    var offset = CGPointZero
    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)
    }
    let clipRect = CGRectMake(-offset.x, -offset.y, (ratio * image.size.width) + delta, (ratio * image.size.height) + delta)
    UIGraphicsBeginImageContextWithOptions(newSize, true, 0.0)
    UIRectClip(clipRect)
    image.drawInRect(clipRect)
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
}

Wenn jemand die objektive c-Version haben möchte, ist sie auf seiner Website.


2

Ich habe festgestellt, dass der Swift 3 von Evgenii Kanvets das Bild nicht einheitlich skaliert.

Hier ist meine Swift 4-Version der Funktion, die das Bild nicht zerquetscht:

static func resizedCroppedImage(image: UIImage, newSize:CGSize) -> UIImage? {

    // This function returns a newImage, based on image
    // - image is scaled uniformaly to fit into a rect of size newSize
    // - if the newSize rect is of a different aspect ratio from the source image
    //     the new image is cropped to be in the center of the source image
    //     (the excess source image is removed)

    var ratio: CGFloat = 0
    var delta: CGFloat = 0
    var drawRect = CGRect()

    if newSize.width > newSize.height {

        ratio = newSize.width / image.size.width
        delta = (ratio * image.size.height) - newSize.height
        drawRect = CGRect(x: 0, y: -delta / 2, width: newSize.width, height: newSize.height + delta)

    } else {

        ratio = newSize.height / image.size.height
        delta = (ratio * image.size.width) - newSize.width
        drawRect = CGRect(x: -delta / 2, y: 0, width: newSize.width + delta, height: newSize.height)

    }

    UIGraphicsBeginImageContextWithOptions(newSize, true, 0.0)
    image.draw(in: drawRect)
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage
} 

Ich musste die Skalierung auf 1,0 Zoll einstellen, UIGraphicsBeginImageContextWithOptionsaber andere funktionierten perfekt. Vielen Dank!
Maxmzd

1

Der folgende einfache Code hat bei mir funktioniert.

[imageView setContentMode:UIViewContentModeScaleAspectFill];
[imageView setClipsToBounds:YES];

Ihr Code funktioniert gut für UIImageViewObjekte. Bei dieser Frage geht es jedoch um die Skalierung des UIImageObjekts selbst.
Rickster

1
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0,0.0,ScreenWidth,ScreenHeigth)];
    [scrollView setBackgroundColor:[UIColor blackColor]];
    [scrollView setDelegate:self];
    [scrollView setShowsHorizontalScrollIndicator:NO];
    [scrollView setShowsVerticalScrollIndicator:NO];
    [scrollView setMaximumZoomScale:2.0];
    image=[image scaleToSize:CGSizeMake(ScreenWidth, ScreenHeigth)];
    imageView = [[UIImageView alloc] initWithImage:image];
    UIImageView* imageViewBk = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]];
    [self.view addSubview:imageViewBk];
    CGRect rect;
    rect.origin.x=0;
    rect.origin.y=0;
    rect.size.width = image.size.width;
    rect.size.height = image.size.height;

    [imageView setFrame:rect];

    [scrollView setContentSize:[imageView frame].size];
    [scrollView setMinimumZoomScale:[scrollView frame].size.width / [imageView frame].size.width];
    [scrollView setZoomScale:[scrollView minimumZoomScale]];
    [scrollView addSubview:imageView];

    [[self view] addSubview:scrollView];

Dann können Sie auf diese Weise Screenshots zu Ihrem Bild machen

float zoomScale = 1.0 / [scrollView zoomScale];
CGRect rect;
rect.origin.x = [scrollView contentOffset].x * zoomScale;
rect.origin.y = [scrollView contentOffset].y * zoomScale;
rect.size.width = [scrollView bounds].size.width * zoomScale;
rect.size.height = [scrollView bounds].size.height * zoomScale;

CGImageRef cr = CGImageCreateWithImageInRect([[imageView image] CGImage], rect);

UIImage *cropped = [UIImage imageWithCGImage:cr];

CGImageRelease(cr);

0
- (UIImage*)imageScale:(CGFloat)scaleFactor cropForSize:(CGSize)targetSize
{
    targetSize = !targetSize.width?self.size:targetSize;
    UIGraphicsBeginImageContext(targetSize); // this will crop

    CGRect thumbnailRect = CGRectZero;

    thumbnailRect.size.width  = targetSize.width*scaleFactor;
    thumbnailRect.size.height = targetSize.height*scaleFactor;
    CGFloat xOffset = (targetSize.width- thumbnailRect.size.width)/2;
    CGFloat yOffset = (targetSize.height- thumbnailRect.size.height)/2;
    thumbnailRect.origin = CGPointMake(xOffset,yOffset);

    [self drawInRect:thumbnailRect];

    UIImage *newImage  = UIGraphicsGetImageFromCurrentImageContext();

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

    UIGraphicsEndImageContext();

    return newImage;
}

Unter dem Arbeitsbeispiel: Linkes Bild - (Ursprungsbild); Rechtes Bild mit Maßstab x2

Geben Sie hier die Bildbeschreibung ein

Wenn Sie das Bild skalieren möchten, aber den Rahmen (Proportionen) beibehalten möchten, rufen Sie die Methode folgendermaßen auf:

[yourImage imageScale:2.0f cropForSize:CGSizeZero];

0

Diese Frage scheint zur Ruhe gekommen zu sein, aber auf meiner Suche nach einer Lösung, die ich leichter verstehen konnte (und die in Swift geschrieben wurde), bin ich zu dieser Frage gekommen (auch gepostet unter: Wie man das UIImage beschneidet? )


Ich wollte in der Lage sein, aus einer Region basierend auf einem Seitenverhältnis zu beschneiden und auf eine Größe zu skalieren, die auf einem Ausmaß der äußeren Begrenzung basiert. Hier ist meine Variation:

import AVFoundation
import ImageIO

class Image {

    class func crop(image:UIImage, crop source:CGRect, aspect:CGSize, outputExtent:CGSize) -> UIImage {

        let sourceRect = AVMakeRectWithAspectRatioInsideRect(aspect, source)
        let targetRect = AVMakeRectWithAspectRatioInsideRect(aspect, CGRect(origin: CGPointZero, size: outputExtent))

        let opaque = true, deviceScale:CGFloat = 0.0 // use scale of device's main screen
        UIGraphicsBeginImageContextWithOptions(targetRect.size, opaque, deviceScale)

        let scale = max(
            targetRect.size.width / sourceRect.size.width,
            targetRect.size.height / sourceRect.size.height)

        let drawRect = CGRect(origin: -sourceRect.origin * scale, size: image.size * scale)
        image.drawInRect(drawRect)

        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return scaledImage
    }
}

Es gibt ein paar Dinge, die ich verwirrend fand, die getrennten Probleme beim Zuschneiden und Ändern der Größe. Das Zuschneiden wird mit dem Ursprung des Rect behandelt, das Sie an drawInRect übergeben, und das Skalieren wird durch den Größenbereich behandelt. In meinem Fall musste ich die Größe des Zuschneide-Rechtecks ​​auf der Quelle mit meinem Ausgangs-Rechteck mit demselben Seitenverhältnis in Beziehung setzen. Der Skalierungsfaktor wird dann ausgegeben / eingegeben und muss auf drawRect angewendet werden (an drawInRect übergeben).

Eine Einschränkung besteht darin, dass bei diesem Ansatz effektiv davon ausgegangen wird, dass das von Ihnen gezeichnete Bild größer als der Bildkontext ist. Ich habe dies nicht getestet, aber ich denke, Sie können diesen Code zum Zuschneiden / Zoomen verwenden, aber den Skalierungsparameter explizit als den oben genannten Skalierungsparameter definieren. Standardmäßig wendet UIKit einen Multiplikator an, der auf der Bildschirmauflösung basiert.

Schließlich sollte angemerkt werden, dass dieser UIKit-Ansatz höher ist als die CoreGraphics / Quartz- und Core Image-Ansätze und Probleme mit der Bildorientierung zu behandeln scheint. Es ist auch erwähnenswert, dass es nach ImageIO ziemlich schnell ist, laut diesem Beitrag hier: http://nshipster.com/image-resizing/


0

Schnelle Version:

    static func imageWithImage(image:UIImage, newSize:CGSize) ->UIImage {
    UIGraphicsBeginImageContextWithOptions(newSize, true, UIScreen.mainScreen().scale);
    image.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))

    let newImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();
    return newImage
}

1
Schöne kleine Funktion, aber ich bin mir ziemlich sicher, dass dies das Bild nur auf eine bestimmte Größe streckt, das Seitenverhältnis und den Zuschnitt nicht beibehält ...
William T.

Ja, Sie haben Recht, dies dient nur dazu, das Bild auf eine paritulare Größe zu bringen.
Roman Barzyczak

0

Hier ist eine Swift 3-Version von Sam Wirchs Swift -Leitfaden von William T.

extension UIImage {

    static func resizedCroppedImage(image: UIImage, newSize:CGSize) -> UIImage? {
        var ratio: CGFloat = 0
        var delta: CGFloat = 0
        var offset = CGPoint.zero

        if image.size.width > image.size.height {
            ratio = newSize.width / image.size.width
            delta = (ratio * image.size.width) - (ratio * image.size.height)
            offset = CGPoint(x: delta / 2, y: 0)
        } else {
            ratio = newSize.width / image.size.height
            delta = (ratio * image.size.height) - (ratio * image.size.width)
            offset = CGPoint(x: 0, y: delta / 2)
        }

        let clipRect = CGRect(x: -offset.x, y: -offset.y, width: (ratio * image.size.width) + delta, height: (ratio * image.size.height) + delta)
        UIGraphicsBeginImageContextWithOptions(newSize, true, 0.0)
        UIRectClip(clipRect)
        image.draw(in: clipRect)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage
    }

}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.