ios - UIImage का आकार बदलने का सबसे आसान तरीका?




resize (19)

मेरे आईफोन ऐप में, मैं कैमरे के साथ एक तस्वीर लेता हूं, फिर मैं इसे 2 9 0 * 3 9 0 पिक्सेल में बदलना चाहता हूं। मैं छवि का आकार बदलने के लिए इस विधि का उपयोग कर रहा था:

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

यह पूरी तरह से काम करता है, लेकिन यह एक अनियंत्रित फ़ंक्शन है, इसलिए मैं इसे अब आईफोन ओएस 4 के साथ उपयोग नहीं कर सकता।

तो ... UIImage का आकार बदलने का सबसे आसान तरीका क्या है?


खिंचाव भरने, पहलू भरने और पहलू फिट के लिए स्विफ्ट समाधान

अपने समाधान के लिए abdullahselek के लिए धन्यवाद।

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

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

    func resizeImage(withSize size: CGSize, scaleMode: ScaleMode = .contentAspectFill) -> UIImage? {
        let aspectWidth = size.width / self.size.width;
        let aspectHeight = size.height / self.size.height;

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

(स्विफ्ट 4 संगत) आईओएस 10+ और आईओएस <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!
    }
}

[सीएफ क्रिस] वांछित आकार में आकार बदलने के लिए :

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

या, समकक्ष, CGImageGetWidth(...)/DESIREDWIDTH


असफलता विकल्प के साथ स्विफ्ट 3.0 (त्रुटि के मामले में मूल छवि देता है):

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
}

इस एक्सटेंशन का प्रयोग करें

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

ऊपर 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;
}

पॉल के कोड में यह सुधार आपको एक आईफोन पर रेटिना डिस्प्ले के साथ एक तेज उच्च रेज छवि देगा। अन्यथा जब यह धुंधला हो जाता है।

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

मुझे ऐप्पल के अपने उदाहरणों में यूआईएममेज के लिए एक श्रेणी मिली जो एक ही चाल करता है। यहां लिंक है: https://developer.apple.com/library/ios/samplecode/sc2273/Listings/AirDropSample_UIImage_Resize_m.html

आपको बस कॉल बदलना होगा:

UIGraphicsBeginImageContextWithOptions(newSize, YES, 2.0);

imageWithImage:scaledToSize:inRect: में imageWithImage:scaledToSize:inRect: साथ:

UIGraphicsBeginImageContextWithOptions(newSize, NO, 2.0);

छवि में अल्फा चैनल पर विचार करने के लिए।


मैंने पाया है कि एक उत्तर खोजना मुश्किल है कि आप अपने स्विफ्ट 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)
    }
}

यह कोड अल्फा चैनल के साथ और बिना छवियों के अतिरिक्त समर्थन के साथ ऐप्पल के विस्तार का एक पुनर्लेख है।

एक और पढ़ने के रूप में मैं विभिन्न छवि आकार बदलने तकनीकों के लिए इस आलेख की जांच करने की सलाह देते हैं। वर्तमान दृष्टिकोण सभ्य प्रदर्शन प्रदान करता है, यह उच्च स्तरीय एपीआई संचालित करता है और समझने में आसान है। मैं तब तक चिपकने की अनुशंसा करता हूं जब तक आप पाते हैं कि छवि का आकार बदलना आपके प्रदर्शन में एक बाधा है।


मैंने यह भी देखा है (जिसे मैं सामान्य और चयनित स्थिति के लिए UIButtons पर उपयोग करता हूं क्योंकि बटन फिट करने के लिए resize नहीं हैं)। क्रेडिट जो भी मूल लेखक था, जाता है।

सबसे पहले एक खाली .h और .m फ़ाइल UIImageResizing.h जिसे 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

उस .m फ़ाइल को उस .m फ़ाइल में शामिल करें जिसे आप फ़ंक्शन का उपयोग करने जा रहे हैं और फिर इसे इस तरह कॉल करें:

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

यदि आप सिर्फ एक छवि को छोटा चाहते हैं और सटीक आकार की परवाह नहीं करते हैं:

+ (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 स्केल सेट करने से आपको 8 एमपी कैमरा से 612 छवियों में 816 0.25f

यहां एक श्रेणी UIImage + स्केल है जिनके लिए एक की आवश्यकता है।


यह स्विफ्ट 3 और स्विफ्ट 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))

यहां मेरा कुछ हद तक वर्बोज़ स्विफ्ट कोड

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://.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
}

सबसे आसान तरीका है अपने 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)];

स्विफ्ट 4 और आईओएस 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))

आईओएस 10+ समाधान के लिए उचित स्विफ्ट 3.0 : 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
    }

और यहां उद्देश्य सी संस्करण है:

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

स्विफ्ट 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()

पॉल लिंच के जवाब का स्विफ्ट संस्करण यहां दिया गया है

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
}

स्विफ्ट 3.0 संस्करण:

func imageWithImage(image:UIImage, scaledToSize newSize:CGSize) -> UIImage{
    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
    image.draw(in: CGRect(origin: CGPoint.zero, size: CGSize(width: newSize.width, height: newSize.height)))
    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return newImage
}

 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
}




resize