วิธีที่ง่ายที่สุดในการปรับขนาด UIImage?


397

ในแอพ iPhone ของฉันฉันถ่ายรูปด้วยกล้องแล้วฉันต้องการปรับขนาดเป็น 290 * 390 พิกเซล ฉันใช้วิธีนี้เพื่อปรับขนาดภาพ:

UIImage *newImage = [image _imageScaledToSize:CGSizeMake(290, 390)
                         interpolationQuality:1];    

มันใช้งานได้ดี แต่มันเป็นฟังก์ชั่นที่ไม่มีเอกสารดังนั้นฉันไม่สามารถใช้กับ iPhone OS4 ได้อีกต่อไป

ดังนั้น ... วิธีที่ง่ายที่สุดในการปรับขนาด UIImage คืออะไร?


วิธีการทำในปี 2562, nshipster.com/image-resizing
dengST30

คำตอบ:


772

วิธีที่ง่ายที่สุดคือการตั้งค่าเฟรมของคุณUIImageViewและตั้งค่าเป็นcontentModeหนึ่งในตัวเลือกการปรับขนาด

หรือคุณสามารถใช้วิธีการยูทิลิตี้นี้หากคุณต้องการปรับขนาดภาพ:

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
    //UIGraphicsBeginImageContext(newSize);
    // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
    // Pass 1.0 to force exact pixel size.
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    return newImage;
}

ตัวอย่างการใช้งาน:

#import "MYUtil.h"

UIImage *myIcon = [MYUtil imageWithImage:myUIImageInstance scaledToSize:CGSizeMake(20, 20)];

11
ฉันจะไม่เก็บผลลัพธ์ไว้ที่นี่ newImageจะถูกลบอัตโนมัติแล้วและควรขึ้นอยู่กับวิธีการที่เรียกสิ่งนี้ว่าจะเก็บไว้หรือไม่ วิธีการนี้เป็นเพียงการขอความจำบั๊กเนื่องจากinitไม่ใช่ส่วนหนึ่งของชื่อเมธอด ฉันคาดว่าจะมีวิธีการที่ชื่อเช่นนี้เพื่อส่งคืนวัตถุอัตโนมัติ
Alex Wayne

จุดที่ถูกต้องและแก้ไข ฉันจะทิ้งไว้ให้ระมัดระวังว่ารหัสของฉันที่ใช้นี้สร้างข้อผิดพลาด malloc ที่อื่นโดยไม่มีการเก็บเพิ่มเติมซึ่งเป็นความผิดของฉันอย่างชัดเจน :-)
พอลลินช์

26
ตั้งแต่ iOS 4.0 , ฟังก์ชั่น UIGraphics * นั้นปลอดภัยสำหรับทุกเธรด
BJ Homer

3
@ Paul ลินช์: เก็บไว้ในใจว่าการเปลี่ยนแปลงนี้แบ่งภารกิจการโพสต์ต้นฉบับ: วิธีการปรับขนาดภาพบางส่วนที่แน่นอนพิกเซลขนาด (เมื่อเทียบกับจุดขนาด)
Nikolai Ruhe

8
สำหรับผู้ที่ดิ้นรนเนื่องจากข้อ จำกัด @NikolaiRuhe ชี้ให้เห็นว่าคุณสามารถบังคับให้มีขนาดพิกเซลที่แน่นอนโดยผ่าน 1.0 แทน 0.0 ในการโทรถึงUIGraphicsBeginImageContextWithOptions
Danny

84

นี่คือคำตอบของPaul Lynchรุ่น Swift

func imageWithImage(image:UIImage, scaledToSize newSize:CGSize) -> UIImage{
    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
    image.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
}

และเป็นส่วนขยาย:

public extension UIImage {
    func copy(newSize: CGSize, retina: Bool = true) -> UIImage? {
        // In next line, pass 0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
        // Pass 1 to force exact pixel size.
        UIGraphicsBeginImageContextWithOptions(
            /* size: */ newSize,
            /* opaque: */ false,
            /* scale: */ retina ? 0 : 1
        )
        defer { UIGraphicsEndImageContext() }

        self.draw(in: CGRect(origin: .zero, size: newSize))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

2
เพิ่งตั้งข้อสังเกตว่าใน iOS ขนาดใหม่ของคุณจะเพิ่มขึ้น 2 เท่าและ 3x ตามอุปกรณ์
Sruit A.Suk

6
UIGraphicsBeginImageContextWithOptions (newSize, false, image.scale); สำหรับอุปกรณ์ทั้งหมด
phnmnn

โปรดทราบว่านี่ไม่ได้ปรับขนาด CGImage พื้นฐาน (อย่างน้อยใน iOS 12.1) ซึ่งเป็นสิ่งที่โอเคตามคำถาม แต่ถ้าคุณเขียนภาพคุณจะต้องใช้ cgImage และคุณจะได้ภาพต้นฉบับ
prewett

72

Swift 3.0 ที่เหมาะสมสำหรับโซลูชันiOS 10+ : การใช้ImageRendererและการปิดไวยากรณ์:

func imageWith(newSize: CGSize) -> UIImage {
    let renderer = UIGraphicsImageRenderer(size: newSize)
    let image = renderer.image { _ in
        self.draw(in: CGRect.init(origin: CGPoint.zero, size: newSize))
    }

    return image.withRenderingMode(self.renderingMode)
}

และนี่คือ Objective-C เวอร์ชัน:

@implementation UIImage (ResizeCategory)
- (UIImage *)imageWithSize:(CGSize)newSize
{
    UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:newSize];
    UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext*_Nonnull myContext) {
        [self drawInRect:(CGRect) {.origin = CGPointZero, .size = newSize}];
    }];
    return [image imageWithRenderingMode:self.renderingMode];
}
@end

1
ทางออกที่หรูหรามากนี่ควรเป็นคำตอบที่ยอมรับได้!
appsunited

2
มันดีกว่าสง่ามันถูกต้อง เอกสาร api ของ Apple แนะนำรหัสใหม่ให้ใช้ UIGraphicsRenderer ตามที่รหัสนี้ทำ ขอบคุณ
Paul Bruneau

1
@appsunited คำถามมีอายุเกือบ 8 ปี และวิธีนี้ใช้ได้กับiOS10 + เท่านั้นตามที่ระบุไว้

เมื่อคัดลอกวัตถุภาพใหม่ไปยังคลิปบอร์ดมันสร้างบล็อกสีขาวสำหรับฉัน มันไม่ได้ปรับขนาดมุมมองภาพจริงเหรอ?
Oliver Dixon

1
ฟังก์ชั่นนี้คืนภาพที่มีความสูง 0 และความกว้าง 0 คาดหวังความสูงได้สูง 9000 สูงและกว้าง 9000
krishan kumar

31

Trevor Howard มีUIImageบางประเภทที่จัดการปรับขนาดได้ค่อนข้างดี หากไม่มีอะไรอื่นคุณสามารถใช้รหัสเป็นตัวอย่าง

หมายเหตุ: ตั้งแต่ iOS 5.1 คำตอบนี้อาจไม่ถูกต้อง ดูความคิดเห็นด้านล่าง


2
ฉันจำเป็นต้องปรับขนาดภาพบางภาพด้วยและก่อนอื่นฉันลองทดสอบการเพิ่มของ Trevor ไปที่ UIImage แต่มีข้อผิดพลาดบางอย่างใน PNG (บางสิ่งเกี่ยวกับช่องอัลฟา) คำตอบที่ได้รับการยอมรับสำหรับคำถามนี้ได้ผลเป็นอย่างดี
Sorig

1
สิ่งนี้ไม่ถูกต้องอีกต่อไป (อย่างน้อยกับ iOS5.1
Jann

@ Jan ดูที่คอมมิชชันด้านล่างโพสต์
vikingosegundo

@Jann ถ้าคุณทำตามการแก้ไขที่แนะนำในความคิดเห็นไปกับ "Matt พูดว่า: 22 พฤศจิกายน 2011 เวลา 17:39 น." เพราะเขาเผยแพร่ colourspaceref (ซึ่งแตกต่างจากวิธีการแก้ปัญหาที่คล้ายกันของ horseshoe7)
Ben Flynn

1
@Sanmai ใช้วิธีการปรับขนาดใด ๆ เหล่านี้ภาพที่สูญเสียความคมชัด มีวิธีใดที่จะทำให้ได้ความคมชัด
vamsi575kg

31

รุ่นที่กะทัดรัดยิ่งขึ้นสำหรับ Swift 4 และ iOS 10+:

extension UIImage {
    func resized(to size: CGSize) -> UIImage {
        return UIGraphicsImageRenderer(size: size).image { _ in
            draw(in: CGRect(origin: .zero, size: size))
        }
    }
}

การใช้งาน:

let resizedImage = image.resized(to: CGSize(width: 50, height: 50))

26

ฉันก็เห็นสิ่งนี้ทำได้เช่นกัน (ซึ่งฉันใช้UIButtonsสำหรับสถานะปกติและเลือกเนื่องจากปุ่มไม่resizeเหมาะ) เครดิตไปที่ใครก็ตามที่ผู้เขียนต้นฉบับ

ก่อนอื่นให้สร้างไฟล์. h และ .m ว่างที่เรียกว่าUIImageResizing.hและUIImageResizing.m

// Put this in UIImageResizing.h
@interface UIImage (Resize)
- (UIImage*)scaleToSize:(CGSize)size;
@end

// Put this in UIImageResizing.m
@implementation UIImage (Resize)

- (UIImage*)scaleToSize:(CGSize)size {
UIGraphicsBeginImageContext(size);

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0.0, size.height);
CGContextScaleCTM(context, 1.0, -1.0);

CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, size.width, size.height), self.CGImage);

UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return scaledImage;
}

@end

รวมไฟล์. h ไว้ในไฟล์. m ที่คุณจะใช้ฟังก์ชั่นแล้วเรียกมันว่า:

UIImage* image = [UIImage imageNamed:@"largeImage.png"];
UIImage* smallImage = [image scaleToSize:CGSizeMake(100.0f,100.0f)];

สิ่งนี้ไม่คัดลอกเหนือการวางแนวภาพ
Kevin

20

การปรับปรุงโค้ดของพอลนี้จะให้ภาพความละเอียดสูงคมชัดบน iPhone ที่มีหน้าจอเรตินา มิฉะนั้นเมื่อลดขนาดลงก็พร่ามัว

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    if ([[UIScreen mainScreen] scale] == 2.0) {
        UIGraphicsBeginImageContextWithOptions(newSize, YES, 2.0);
    } else {
        UIGraphicsBeginImageContext(newSize);
    }
} else {
    UIGraphicsBeginImageContext(newSize);
}
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
UIGraphicsEndImageContext();
return newImage;
}

13
เพียงแค่ FYI การเปลี่ยนแปลงที่คุณทำนั้นไม่จำเป็นเนื่องจากการจัดหาค่า 0.0 สำหรับสเกลในUIGraphicsBeginImageContextWithOptionsจะใช้สเกลของหน้าจอหลักโดยอัตโนมัติ (ตั้งแต่ iOS 3.2)
แอนดรูว์อาร์

16

นี่เป็นวิธีง่ายๆ:

    UIImage * image = [UIImage imageNamed:@"image"];
    CGSize sacleSize = CGSizeMake(10, 10);
    UIGraphicsBeginImageContextWithOptions(sacleSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, sacleSize.width, sacleSize.height)];
    UIImage * resizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

resizedImageเป็นภาพใหม่


16

วิธีการแก้ปัญหาที่รวดเร็วสำหรับการถ่างขยาย, เติมมุมมองและปรับพอดี

extension UIImage {
    enum ContentMode {
        case contentFill
        case contentAspectFill
        case contentAspectFit
    }

    func resize(withSize size: CGSize, contentMode: ContentMode = .contentAspectFill) -> UIImage? {
        let aspectWidth = size.width / self.size.width
        let aspectHeight = size.height / self.size.height

        switch contentMode {
        case .contentFill:
            return resize(withSize: size)
        case .contentAspectFit:
            let aspectRatio = min(aspectWidth, aspectHeight)
            return resize(withSize: CGSize(width: self.size.width * aspectRatio, height: self.size.height * aspectRatio))
        case .contentAspectFill:
            let aspectRatio = max(aspectWidth, aspectHeight)
            return resize(withSize: CGSize(width: self.size.width * aspectRatio, height: self.size.height * aspectRatio))
        }
    }

    private func resize(withSize size: CGSize) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(size, false, self.scale)
        defer { UIGraphicsEndImageContext() }
        draw(in: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

และในการใช้งานคุณสามารถทำสิ่งต่อไปนี้:

let image = UIImage(named: "image.png")!
let newImage = image.resize(withSize: CGSize(width: 200, height: 150), contentMode: .contentAspectFill)

ขอบคุณ Abdullahselek สำหรับวิธีแก้ปัญหาดั้งเดิมของเขา


15

นี่คือการแก้ไขหมวดหมู่ที่เขียนโดย iWasRobbed ด้านบน มันรักษาอัตราส่วนภาพของภาพต้นฉบับแทนที่จะบิดเบือน

- (UIImage*)scaleToSizeKeepAspect:(CGSize)size {
    UIGraphicsBeginImageContext(size);

    CGFloat ws = size.width/self.size.width;
    CGFloat hs = size.height/self.size.height;

    if (ws > hs) {
        ws = hs/ws;
        hs = 1.0;
    } else {
        hs = ws/hs;
        ws = 1.0;
    }

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0.0, size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    CGContextDrawImage(context, CGRectMake(size.width/2-(size.width*ws)/2,
        size.height/2-(size.height*hs)/2, size.width*ws,
        size.height*hs), self.CGImage);

    UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return scaledImage;
}

11

หากคุณต้องการภาพที่เล็กลงและไม่สนใจขนาดที่แน่นอน:

+ (UIImage *)imageWithImage:(UIImage *)image scaledToScale:(CGFloat)scale
{
    UIGraphicsBeginImageContextWithOptions(self.size, YES, scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
    [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

การตั้งค่าสเกลเป็น0.25fจะให้ภาพ 816 x 612 จากกล้อง 8MP

นี่คือหมวดหมู่ UIImage + Scaleสำหรับผู้ที่ต้องการ


10

ทำไมจึงซับซ้อน ฉันคิดว่าการใช้ system API สามารถบรรลุผลลัพธ์เดียวกัน:

UIImage *largeImage;
CGFloat ratio = 0.4; // you want to get a new image that is 40% the size of large image.
UIImage *newImage = [UIImage imageWithCGImage:largeImage.CGImage
                                        scale:1/ratio
                                  orientation:largeImage.imageOrientation];
// notice the second argument, it is 1/ratio, not ratio.

gotcha เพียงอย่างเดียวคือคุณควรผ่านอัตราส่วนผกผันของเป้าหมายเป็นอาร์กิวเมนต์ที่สองตามเอกสารพารามิเตอร์ที่สองระบุอัตราส่วนของภาพต้นฉบับเมื่อเทียบกับอัตราส่วนที่ปรับใหม่


เนื่องจากสเกล (%) ไม่เหมือนกับพิกเซล (w / h)

มาตราส่วนควรมีขนาดใหญ่ภาพขนาด / อัตราส่วนไม่ได้ 1 / อัตราส่วน
MariánČerný

9

นี่คือส่วนขยาย UIImage ที่เข้ากันได้กับSwift 3และSwift 4ซึ่งปรับขนาดภาพตามขนาดที่กำหนดด้วยอัตราส่วนภาพ

extension UIImage {

    func scaledImage(withSize size: CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
        defer { UIGraphicsEndImageContext() }
        draw(in: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
        return UIGraphicsGetImageFromCurrentImageContext()!
    }

    func scaleImageToFitSize(size: CGSize) -> UIImage {
        let aspect = self.size.width / self.size.height
        if size.width / aspect <= size.height {
            return scaledImage(withSize: CGSize(width: size.width, height: size.width / aspect))
        } else {
            return scaledImage(withSize: CGSize(width: size.height * aspect, height: size.height))
        }
    }

}

ตัวอย่างการใช้งาน

let image = UIImage(named: "apple")
let scaledImage = image.scaleImageToFitSize(size: CGSize(width: 45.0, height: 45.0))

ผมอยากจะแนะนำให้ชื่อฟังก์ชันหรือscaledImage(with size:) scaledWithSize(_:)ยัง UIGraphicsGetImageFromCurrentImageContextไม่สามารถกลับมาได้จริง ๆnilดังนั้นจึง!ใช้ได้เช่นกัน CGRect(origin: .zero, size: size)นอกจากนี้คุณยังสามารถลดความซับซ้อนของการสร้างการดูแลรักษา
Sulthan

8

ฉันพบหมวดหมู่ของ UIImage ในตัวอย่างของ Apple เองซึ่งทำแบบเดียวกัน นี่คือการเชื่อมโยง: https://developer.apple.com/library/ios/samplecode/sc2273/Listings/AirDropSample_UIImage_Resize_m.html

คุณจะต้องเปลี่ยนการโทร:

UIGraphicsBeginImageContextWithOptions(newSize, YES, 2.0);

ในimageWithImage:scaledToSize:inRect:ด้วย:

UIGraphicsBeginImageContextWithOptions(newSize, NO, 2.0);

เพื่อพิจารณาช่องอัลฟ่าในภาพ


6
 func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage 
{
        let scale = newWidth / image.size.width
        let newHeight = image.size.height * scale
        UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight))
        image.drawInRect(CGRectMake(0, 0, newWidth, newHeight))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
}

เป็นความคิดที่ดีที่จะเพิ่มข้อความอธิบายลงไปในโค้ดของคุณ
GMchris

6

สำหรับเพื่อน Xamarians ของฉันนี่คือคำตอบ@Paul Lynchรุ่นXamarin.iOS

private UIImage ResizeImage(UIImage image, CGSize newSize) 
{
    UIGraphics.BeginImageContextWithOptions(newSize, false, 0.0f);
    image.Draw(new CGRect(0, 0, newSize.Width, newSize.Height));
    UIImage newImage = UIGraphics.GetImageFromCurrentImageContext();
    UIGraphics.EndImageContext();
    return newImage;
}

5

หากคุณต้องการสร้างภาพขนาดย่อของ UIImage (ด้วยการปรับขนาดตามสัดส่วนหรือการครอบตัดบางส่วน) ให้ดูที่หมวดหมู่UIImage + ปรับขนาดที่ช่วยให้คุณใช้ไวยากรณ์ที่คล้ายกับ ImageMagick ที่กระชับ:

UIImage* squareImage       = [image resizedImageByMagick: @"320x320#"];

5

[CF คริส] เมื่อต้องการปรับขนาดเพื่อให้มีขนาดที่ต้องการ:

UIImage *after = [UIImage imageWithCGImage:before.CGImage
                                     scale:CGImageGetHeight(before.CGImage)/DESIREDHEIGHT
                               orientation:UIImageOrientationUp];

หรืออย่างเท่าเทียมกันทดแทน CGImageGetWidth(...)/DESIREDWIDTH


โปรดทราบว่าข้อมูลภาพนั้นไม่ได้ถูกปรับขนาด แต่จะใช้ตัวคูณสเกลซึ่งหมายความว่าภาพมีขนาดเท่ากันในหน่วยความจำ
inkredibl

5

Rogerio Chavesตอบเป็นส่วนขยายที่รวดเร็ว

func scaledTo(size: CGSize) -> UIImage{
    UIGraphicsBeginImageContextWithOptions(size, false, 0.0);
    self.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return newImage
}

และโบนัสอีกด้วย

func scaledTo(height: CGFloat) -> UIImage{
    let width = height*self.size.width/self.size.height
    return scaledTo(size: CGSize(width: width, height: height))
}

5

Swift 3.0 พร้อมตัวเลือก failafe (คืนค่ารูปภาพดั้งเดิมในกรณีที่มีข้อผิดพลาด):

func resize(image: UIImage, toSize size: CGSize) -> UIImage{
    UIGraphicsBeginImageContextWithOptions(size,false,1.0)
    image.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
    if let resizedImage = UIGraphicsGetImageFromCurrentImageContext() {
        UIGraphicsEndImageContext()
        return resizedImage
    }
    UIGraphicsEndImageContext()
    return image
}

5

(เข้ากันได้กับ Swift 4) โซลูชัน iOS 10+ และ iOS <10 (ใช้UIGraphicsImageRendererเป็นUIGraphicsGetImageFromCurrentImageContextอย่างอื่น)

/// Resizes an image
///
/// - Parameter newSize: New size
/// - Returns: Resized image
func scaled(to newSize: CGSize) -> UIImage {
    let rect = CGRect(origin: .zero, size: newSize)

    if #available(iOS 10, *) {
        let renderer = UIGraphicsImageRenderer(size: newSize)
        return renderer.image { _ in
            self.draw(in: rect)
        }
    } else {
        UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
        self.draw(in: rect)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage!
    }
}

5

วิธีการที่มีประสิทธิภาพโดยไม่ต้องยืดภาพ Swift 4

// Method to resize image
func resize(image: UIImage, toScaleSize:CGSize) -> UIImage {
                UIGraphicsBeginImageContextWithOptions(toScaleSize, true, image.scale)
                        image.draw(in: CGRect(x: 0, y: 0, width: toScaleSize.width, height: toScaleSize.height))
                        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
                        UIGraphicsEndImageContext()
                        return scaledImage!
                }

// วิธีการโทร

    let resizedImage = self.resize(image: UIImage(named: "YourImageName")!, toScaleSize: CGSize(width: 290, height: 390))

3

@Paul Lynch คำตอบนั้นยอดเยี่ยม แต่มันจะเปลี่ยนอัตราส่วนภาพ หากคุณไม่ต้องการเปลี่ยนอัตราส่วนภาพและยังต้องการภาพใหม่ที่เหมาะกับขนาดใหม่ลองทำสิ่งนี้

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {

// calculate a new size which ratio is same to original image
CGFloat ratioW = image.size.width / newSize.width;
CGFloat ratioH = image.size.height / newSize.height;

CGFloat ratio = image.size.width / image.size.height;

CGSize showSize = CGSizeZero;
if (ratioW > 1 && ratioH > 1) { 

    if (ratioW > ratioH) { 
        showSize.width = newSize.width;
        showSize.height = showSize.width / ratio;
    } else {
        showSize.height = newSize.height;
        showSize.width = showSize.height * ratio;
    }

} else if (ratioW > 1) {

    showSize.width = showSize.width;
    showSize.height = showSize.width / ratio;

} else if (ratioH > 1) {

    showSize.height = showSize.height;
    showSize.width = showSize.height * ratio;

}

//UIGraphicsBeginImageContext(newSize);
// In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
// Pass 1.0 to force exact pixel size.
UIGraphicsBeginImageContextWithOptions(showSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, showSize.width, showSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;}

3

ใช้ส่วนขยายนี้

extension UIImage {
    public func resize(size:CGSize, completionHandler:(resizedImage:UIImage, data:NSData?)->()) {
        dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in
            let newSize:CGSize = size
            let rect = CGRectMake(0, 0, newSize.width, newSize.height)
            UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
            self.drawInRect(rect)
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            let imageData = UIImageJPEGRepresentation(newImage, 0.5)
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                completionHandler(resizedImage: newImage, data:imageData)
            })
        })
    }
}

2

Swift 2.0:

let image = UIImage(named: "imageName")
let newSize = CGSize(width: 10, height: 10)

UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
image?.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
let imageResized = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

2

นี่คือโค้ด Swift ที่ค่อนข้างละเอียดของฉัน

func scaleImage(image:UIImage,  toSize:CGSize) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(toSize, false, 0.0);

    let aspectRatioAwareSize = self.aspectRatioAwareSize(image.size, boxSize: toSize, useLetterBox: false)


    let leftMargin = (toSize.width - aspectRatioAwareSize.width) * 0.5
    let topMargin = (toSize.height - aspectRatioAwareSize.height) * 0.5


    image.drawInRect(CGRectMake(leftMargin, topMargin, aspectRatioAwareSize.width , aspectRatioAwareSize.height))
    let retVal = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return retVal
}

func aspectRatioAwareSize(imageSize: CGSize, boxSize: CGSize, useLetterBox: Bool) -> CGSize {
    // aspect ratio aware size
    // http://stackoverflow.com/a/6565988/8047
    let imageWidth = imageSize.width
    let imageHeight = imageSize.height
    let containerWidth = boxSize.width
    let containerHeight = boxSize.height

    let imageAspectRatio = imageWidth/imageHeight
    let containerAspectRatio = containerWidth/containerHeight

    let retVal : CGSize
    // use the else at your own risk: it seems to work, but I don't know 
    // the math
    if (useLetterBox) {
        retVal = containerAspectRatio > imageAspectRatio ? CGSizeMake(imageWidth * containerHeight / imageHeight, containerHeight) : CGSizeMake(containerWidth, imageHeight * containerWidth / imageWidth)
    } else {
        retVal = containerAspectRatio < imageAspectRatio ? CGSizeMake(imageWidth * containerHeight / imageHeight, containerHeight) : CGSizeMake(containerWidth, imageHeight * containerWidth / imageWidth)
    }

    return retVal
}

1
สิ่งนี้ช่วยประหยัดเวลาของฉัน ขอบคุณ!
Quy Nguyen

มีประโยชน์ แต่ทำตัวแปลก ๆ หลังจากทำกิจกรรมต่อและกลับมาดูที่นี่ได้ที่นี่: stackoverflow.com/questions/30978685//
เขา Yifei

โปรดทราบ: คุณอาจต้องการเพิ่ม precondition ( guard) ในaspectRatioAwareSizeฟังก์ชั่นดังกล่าวว่ามันจะไม่หารด้วยศูนย์ยกเว้นถ้าพารามิเตอร์อินพุตสำหรับ imageSize หรือ boxSize คือCGSize.zero
pkluz

@pkluz นี่เป็นข้อเสนอแนะที่ดี แต่คุณต้องการมันมากกว่าฟังก์ชั่นฉันคิดว่าเนื่องจากตัวแปรแต่ละตัวเป็นตัวหารของอีกบรรทัดหนึ่ง ... ฉันจะปล่อยมันไว้เพื่อความชัดเจน สำหรับการผลิตหรือห้องสมุดสำหรับ GitHub คุณอาจต้องการที่จะเพิ่มพูน ... มากกว่าผู้พิทักษ์ฉันกังวลว่าฟังก์ชั่นนี้ใช้ชื่อตัวแปรสั้น ๆ ที่ไม่พูดอะไรมาก ฉันอาจจะแก้ไขสิ่งนั้นก่อนแล้วจึงเพิ่มการ์ดสำหรับสิ่งอื่นแล้วเพิ่มการทดสอบหน่วย
Dan Rosenstark

2

Swift 4 คำตอบ:

func scaleDown(image: UIImage, withSize: CGSize) -> UIImage {
    let scale = UIScreen.main.scale
    UIGraphicsBeginImageContextWithOptions(withSize, false, scale)
    image.draw(in: CGRect(x: 0, y: 0, width: withSize.width, height: withSize.height))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage!
}

ไม่จำเป็นต้องตั้งมาตราส่วนที่แท้จริง:The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
ธาน

1

ฉันพบว่ามันยากที่จะหาคำตอบที่คุณสามารถใช้นอกกรอบในโครงการSwift 3 ของคุณ ปัญหาหลักของคำตอบอื่น ๆ ที่พวกเขาไม่เคารพอัลฟาช่องของภาพ นี่คือเทคนิคที่ฉันใช้ในโครงการของฉัน

extension UIImage {

    func scaledToFit(toSize newSize: CGSize) -> UIImage {
        if (size.width < newSize.width && size.height < newSize.height) {
            return copy() as! UIImage
        }

        let widthScale = newSize.width / size.width
        let heightScale = newSize.height / size.height

        let scaleFactor = widthScale < heightScale ? widthScale : heightScale
        let scaledSize = CGSize(width: size.width * scaleFactor, height: size.height * scaleFactor)

        return self.scaled(toSize: scaledSize, in: CGRect(x: 0.0, y: 0.0, width: scaledSize.width, height: scaledSize.height))
    }

    func scaled(toSize newSize: CGSize, in rect: CGRect) -> UIImage {
        if UIScreen.main.scale == 2.0 {
            UIGraphicsBeginImageContextWithOptions(newSize, !hasAlphaChannel, 2.0)
        }
        else {
            UIGraphicsBeginImageContext(newSize)
        }

        draw(in: rect)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage ?? UIImage()
    }

    var hasAlphaChannel: Bool {
        guard let alpha = cgImage?.alphaInfo else {
            return false
        }
        return alpha == CGImageAlphaInfo.first ||
            alpha == CGImageAlphaInfo.last ||
            alpha == CGImageAlphaInfo.premultipliedFirst ||
            alpha == CGImageAlphaInfo.premultipliedLast
    }
}

ตัวอย่างการใช้งาน:

override func viewDidLoad() {
    super.viewDidLoad()

    let size = CGSize(width: 14.0, height: 14.0)
    if let image = UIImage(named: "barbell")?.scaledToFit(toSize: size) {
        let imageView = UIImageView(image: image)
        imageView.center = CGPoint(x: 100, y: 100)
        view.addSubview(imageView)
    }
}

รหัสนี้เป็นส่วนเสริมของแอปเปิ้ลที่เขียนใหม่พร้อมการรองรับภาพที่มีและไม่มีช่องอัลฟา

เป็นการอ่านเพิ่มเติมฉันแนะนำให้ตรวจสอบบทความนี้สำหรับเทคนิคการปรับขนาดรูปภาพต่าง ๆ แนวทางปัจจุบันมีประสิทธิภาพที่ดีใช้งาน API ระดับสูงและเข้าใจง่าย ฉันขอแนะนำให้ติดมันจนกว่าคุณจะพบว่าการปรับขนาดภาพเป็นคอขวดในประสิทธิภาพของคุณ


1

ใช้ส่วนขยายนี้ในกรณีที่คุณต้องการปรับขนาดความกว้าง / ความสูงด้วยอัตราส่วนกว้างยาวเท่านั้น

extension UIImage {
    func resize(to size: CGSize) -> UIImage {
        return UIGraphicsImageRenderer(size: size).image { _ in
            draw(in: CGRect(origin: .zero, size: size))
        }
    }
    func resize(width: CGFloat) -> UIImage {
        return resize(to: CGSize(width: width, height: width / (size.width / size.height)))
    }
    func resize(height: CGFloat) -> UIImage {
        return resize(to: CGSize(width: height * (size.width / size.height), height: height))
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.