UIImage: Thay đổi kích thước, sau đó cắt


187

Tôi đã vùi mặt vào cái này trong nhiều ngày theo nghĩa đen và mặc dù tôi cảm thấy liên tục rằng tôi đang ở bên lề của sự mặc khải, tôi chỉ đơn giản là không thể đạt được mục tiêu của mình.

Tôi nghĩ, trước thời hạn trong các giai đoạn khái niệm trong thiết kế của tôi, rằng việc lấy một hình ảnh từ máy ảnh hoặc thư viện của iPhone sẽ là một vấn đề tầm thường, sử dụng chức năng tương đương với tùy chọn Aspect Fill UIImageView (hoàn toàn bằng mã), và sau đó cắt bỏ mọi thứ không phù hợp với CGRect đã thông qua.

Lấy hình ảnh gốc từ máy ảnh hoặc thư viện, là chuyện nhỏ. Tôi bị sốc khi thấy hai bước còn lại khó khăn đến thế nào.

Hình ảnh đính kèm cho thấy những gì tôi đang cố gắng để đạt được. Ai đó làm ơn tử tế để nắm tay tôi chứ? Mỗi ví dụ mã tôi đã tìm thấy cho đến nay dường như đập vỡ hình ảnh, lộn ngược, trông giống như tào lao, rút ​​ra khỏi giới hạn, hoặc nếu không chỉ là không hoạt động chính xác.


7
Liên kết bị hỏng với hình ảnh của bạn.

1
Một điều không có gì nếu chúng ta bị sốc là tại sao Apple không thêm nó vào UIImagePickerControll - nó quá khó khăn ;-)
Tim

Câu trả lời:


246

Tôi cần điều tương tự - trong trường hợp của tôi, để chọn kích thước vừa vặn một lần, sau đó cắt từng đầu để khớp với phần còn lại theo chiều rộng. (Tôi đang làm việc trong phong cảnh, vì vậy có thể không nhận thấy bất kỳ thiếu sót nào trong chế độ dọc.) Đây là mã của tôi - đó là một phần của một categeory trên UIImage. Kích thước mục tiêu trong mã của tôi luôn được đặt thành kích thước toàn màn hình của thiết bị.

@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
Thật kỳ lạ, nó hoạt động trong trình giả lập nhưng trên thiết bị tôi nhận được ExecBadAccess ..
Sorin Antohi

5
Vấn đề với thực thi xấu xảy ra, bởi vì các hàm UIImage không phải là luồng an toàn. Đó là lý do tại sao đôi khi nó gặp sự cố, đôi khi không
Erik

1
Mã này làm việc rất tốt cho tôi, nhưng nó bị mờ trên võng mạc. Kết hợp mã này với nhận xét bên dưới đã khiến mọi thứ trở nên hoàn hảo: stackoverflow.com/questions/603907/ trên
MaxGabriel

23
Sử dụng UIGraphicsBeginImageContextWithOptions (targetSize, CÓ, 0,0); để làm cho hình ảnh đẹp trên võng mạc cũng.
Borut Tomazin

1
Điều này làm việc cho tôi trong chế độ Chân dung, nhưng không phải phong cảnh. Chiều cao được kéo dài trong cảnh quan. Bất cứ ý tưởng tại sao?
Darren

77

Một bài đăng cũ hơn chứa mã cho một phương pháp để thay đổi kích thước UIImage của bạn. Phần liên quan như sau:

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

   return newImage;
}

Theo như cắt xén, tôi tin rằng nếu bạn thay đổi phương thức sử dụng kích thước khác cho tỷ lệ thay vì bối cảnh, hình ảnh kết quả của bạn sẽ được cắt theo giới hạn của bối cảnh.


3
Không có lý do tại sao điều này khắc phục hướng hình ảnh, nhưng nó làm và do đó nó đã khắc phục vấn đề của tôi với máy ảnh không trả lại hướng đúng trong originalImage. Cảm ơn.
Brenden

10
Tôi thấy rằng thay đổi kích thước hình ảnh trên thiết bị võng mạc có vẻ mờ. Để duy trì sự rõ ràng, tôi đã sửa đổi dòng đầu tiên thành sau : UIGraphicsBeginImageContextWithOptions(newSize, 1.0f, 0.0f);. (giải thích tại đây: stackoverflow.com/questions/4334233/
johngraham

Nó xoay hình ảnh - nhưng không cắt đúng cách! Tại sao nó có nhiều phiếu bầu như vậy?
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;
}

Tôi đề xuất cái này Cô ấy không phải là một người đẹp sao? ;)


1
Điều này là tốt, nếu bạn loại bỏ đầu tiên nếu tuyên bố nó hoạt động như AspectFill.
RaffAl


7

Bạn đi đây Điều này là hoàn hảo ;-)

EDIT: xem bình luận bên dưới - "Không hoạt động với một số hình ảnh nhất định, không thành công với: CGContextSetInterpolationQuality: lỗi bối cảnh 0x0 không hợp lệ"

// 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
Trông rất đẹp :) Tôi thích Nội suy Chất lượng ở đây
Kostiantyn Sokolinskyi

Không hoạt động với một số hình ảnh nhất định, không thành công với: CGContextSetInterpolationQuality: lỗi bối cảnh 0x0 không hợp lệ
RaffAl

6

Đây là phiên bản câu trả lời của Jane Sales trong Swift. Chúc mừng!

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

Tôi đã sửa đổi Mã của Brad Larson. Nó sẽ khía cạnh điền vào hình ảnh trong chỉnh lưu nhất định.

-(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
Thử nghiệm với hai hình ảnh khác, chân dung và phong cảnh. Điều này KHÔNG thực hiện Fill Aspect.
RaffAl

2

Phiên bản Xamarin.iOS cho câu trả lời được chấp nhận về cách thay đổi kích thước và sau đó cắt UIImage (Aspect Fill) bên dưới

    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

Tôi đã chuyển đổi hướng dẫn của Sam Wirch sang swift và nó hoạt động tốt với tôi, mặc dù có một chút "squishing" trong hình ảnh cuối cùng mà tôi không thể giải quyết.

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
}

Nếu bất cứ ai muốn phiên bản mục tiêu c, nó trên trang web của mình.


2

Tôi thấy rằng Swift 3 được đăng bởi Evgenii Kanvets không thống nhất tỷ lệ hình ảnh.

Đây là phiên bản Swift 4 của chức năng không squish hình ảnh:

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
} 

Tôi đã phải đặt tỷ lệ thành 1.0 in UIGraphicsBeginImageContextWithOptionsnhưng những cái khác hoạt động hoàn hảo. Cảm ơn!
maxmzd

1

Các mã đơn giản sau đây làm việc cho tôi.

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

Mã của bạn không hoạt động tốt cho UIImageViewcác đối tượng. Tuy nhiên, câu hỏi này là về việc nhân rộng UIImageđối tượng.
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];

sau đó bạn có thể chụp ảnh màn hình vào hình ảnh của bạn bằng cách này

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

Bên dưới ví dụ về công việc: Hình ảnh bên trái - (hình ảnh gốc); Hình ảnh bên phải với tỷ lệ x2

nhập mô tả hình ảnh ở đây

Nếu bạn muốn chia tỷ lệ hình ảnh nhưng giữ lại khung hình (tỷ lệ), hãy gọi phương thức theo cách này:

[yourImage imageScale:2.0f cropForSize:CGSizeZero];

0

Câu hỏi này dường như đã được đặt ra, nhưng trong quá trình tìm kiếm một giải pháp mà tôi có thể dễ hiểu hơn (và được viết bằng Swift), tôi đã đến đây (cũng được đăng lên: Làm thế nào để cắt UIImage? )


Tôi muốn có thể cắt từ một khu vực dựa trên tỷ lệ khung hình và tỷ lệ thành kích thước dựa trên phạm vi giới hạn bên ngoài. Đây là biến thể của tôi:

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

Có một vài điều mà tôi thấy khó hiểu, những mối quan tâm riêng biệt của việc cắt xén và thay đổi kích thước. Cắt xén được xử lý với nguồn gốc của trực tràng mà bạn chuyển đến drawInRect và tỷ lệ được xử lý bởi phần kích thước. Trong trường hợp của tôi, tôi cần liên quan đến kích thước của trực tiếp cắt xén trên nguồn, với chỉnh lưu đầu ra của tôi có cùng tỷ lệ khung hình. Hệ số tỷ lệ sau đó là đầu ra / đầu vào và điều này cần được áp dụng cho drawRect (được truyền cho drawInRect).

Một lưu ý là cách tiếp cận này giả định một cách hiệu quả rằng hình ảnh bạn đang vẽ lớn hơn bối cảnh hình ảnh. Tôi chưa thử nghiệm điều này, nhưng tôi nghĩ bạn có thể sử dụng mã này để xử lý cắt / thu phóng, nhưng xác định rõ ràng tham số tỷ lệ là tham số tỷ lệ đã nói ở trên. Theo mặc định, UIKit áp dụng hệ số nhân dựa trên độ phân giải màn hình.

Cuối cùng, cần lưu ý rằng phương pháp UIKit này ở cấp độ cao hơn so với phương pháp CoreGraphics / Quartz và Core Image, và dường như xử lý các vấn đề định hướng hình ảnh. Điều đáng nói là nó khá nhanh, đứng thứ hai sau ImageIO, theo bài đăng này tại đây: http://nshipster.com/image-resizing/


0

Phiên bản Swift:

    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
Chức năng nhỏ xinh nhưng tôi khá chắc chắn rằng điều này chỉ kéo dài hình ảnh đến một kích thước cụ thể, không giữ tỷ lệ khung hình và cắt xén ...
William T.

Có bạn có quyền, điều này chỉ dành cho việc chỉnh sửa hình ảnh thành một kích thước chi tiết.
Roman Barzyczak

0

Dưới đây là phiên bản Swift 3 của hướng dẫn Sam Wirch về swift được đăng bởi 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
    }

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.