IOS के साथ छवि आकार आसानी से आकार बदलने / अनुकूलित करने के लिए कैसे?


114

मेरा एप्लिकेशन नेटवर्क से छवि फ़ाइलों का एक सेट डाउनलोड कर रहा है, और उन्हें स्थानीय iPhone डिस्क पर सहेज रहा है। उन छवियों में से कुछ आकार में बहुत बड़ी हैं (उदाहरण के लिए, 500 पिक्सेल से बड़ी चौड़ाई)। चूंकि iPhone में छवि को उसके मूल आकार में दिखाने के लिए एक बड़ा पर्याप्त डिस्प्ले नहीं है, इसलिए मैं अंतरिक्ष / प्रदर्शन को बचाने के लिए छवि को थोड़ा छोटा करने की योजना बना रहा हूं।

इसके अलावा, उन छवियों में से कुछ JPEG हैं और उन्हें सामान्य 60% गुणवत्ता सेटिंग के रूप में सहेजा नहीं गया है।

मैं iPhone SDK के साथ एक तस्वीर का आकार कैसे बदल सकता हूं, और मैं JPEG छवि की गुणवत्ता सेटिंग कैसे बदल सकता हूं?

जवाबों:


246

इस प्रश्न के उत्तर के रूप में कुछ सुझाव दिए गए हैं । मैंने इस पोस्ट में वर्णित तकनीक को प्रासंगिक कोड के साथ सुझाया था :

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

   return newImage;
}

जहाँ तक छवि का भंडारण, iPhone के साथ उपयोग करने के लिए सबसे तेज़ छवि प्रारूप PNG है, क्योंकि इसमें उस प्रारूप के लिए अनुकूलन हैं। हालाँकि, यदि आप इन छवियों को JPEGs के रूप में संग्रहीत करना चाहते हैं, तो आप अपना UIImage ले सकते हैं और निम्नलिखित कार्य कर सकते हैं:

NSData *dataForJPEGFile = UIImageJPEGRepresentation(theImage, 0.6);

यह एक NSData उदाहरण बनाता है जिसमें 60% गुणवत्ता सेटिंग में JPEG छवि के लिए कच्ची बाइट्स होती हैं। उस NSData उदाहरण की सामग्री को तब डिस्क में लिखा जा सकता है या मेमोरी में कैश्ड किया जा सकता है।


1
साहब ... मैंने एक ही तर्क लिखा है लेकिन एक सफेद सीधी रेखा दिखाई देगी (चित्र) दाईं ओर plz मुझे समाधान दें
नाग_फोन

1
नमस्ते, आकार बदलने के दौरान हम पहलू अनुपात और क्लिप को कैसे बनाए रखते हैं? मेरे मामले में, जब मैं एक ऐसी छवि का आकार बदलता हूं जिसमें एक अलग राशन होता है, तो "समाचार करें", मुझे एक विकृत आकार की छवि मिलती है। धन्यवाद!
वान डू ट्रान

1
यह अतीत में काम किया है, लेकिन iOS5.0.1 और बाद में, यह एक स्मृति रिसाव में जिसके परिणामस्वरूप है। इसे पूरा करने का कोई और तरीका?
उस्मान निसार

बेहतर प्रदर्शन के लिए [Image drawInRect: rect mixMode: kCGBlendModeCopy अल्फ़ा: 1.0] का उपयोग करने की सलाह देते हैं (ताकि ड्रॉ के दौरान ब्लेंडिंग कैलकुलेशन न करना
पड़े

आपको UIGraphicsBeginImageContextWithOptions (size, NO, 0.0) का उपयोग करना चाहिए; जहाँ 0.0 मुख्य रेटिना और उससे ऊपर के समर्थन के लिए मुख्य स्क्रीन स्केल का उपयोग करेगा। Apple बताता है कि "आपको आम तौर पर इसी तरह के UIGraphicsBeginImageContext फ़ंक्शन को कॉल करने से बचना चाहिए (पीछे की संगतता के लिए एक वापसी के रूप में छोड़कर)"।
ब्रैड गॉस

65

आपकी छवियों को आकार देने का सबसे आसान और सरल तरीका यही होगा

float actualHeight = image.size.height;
float actualWidth = image.size.width;
float imgRatio = actualWidth/actualHeight;
float maxRatio = 320.0/480.0;

if(imgRatio!=maxRatio){
    if(imgRatio < maxRatio){
        imgRatio = 480.0 / actualHeight;
        actualWidth = imgRatio * actualWidth;
        actualHeight = 480.0;
    }
    else{
        imgRatio = 320.0 / actualWidth;
        actualHeight = imgRatio * actualHeight;
        actualWidth = 320.0;
    }
}
CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
UIGraphicsBeginImageContext(rect.size);
[image drawInRect:rect];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

ये सुन्दर है। मैं रेटिना-डिस्प्ले रिज़ॉल्यूशन (हालांकि मैंने 320.0 और 480.0 मानों को 640.0 और 1136.0 में बदल दिया) को बनाए रखते हुए 1Mb से 100k तक एक सर्वर पर भेजे गए चित्रों को ट्रिम करने में सक्षम था और स्केलिंग के बाद कुछ JPEG संपीड़न भी किया था: UIImageJPEGRepresentation (img,) 0.7f);
केलर

2
क्या होगा यदि छवि अनुपात और अधिकतम अनुपात समान हो? उदाहरण के लिए, यदि iamge का आकार 3200x4800 है?
अक्षय

यह अतीत में काम किया है, लेकिन iOS5.0.1 और बाद में, यह एक स्मृति रिसाव में जिसके परिणामस्वरूप है। इसे पूरा करने का कोई और तरीका?
उस्मान निसार

25

उपरोक्त विधियां छोटी छवियों के लिए अच्छी तरह से काम करती हैं, लेकिन जब आप एक बहुत बड़ी छवि का आकार बदलने की कोशिश करते हैं, तो आप जल्दी से मेमोरी से बाहर निकल जाएंगे और ऐप को क्रैश कर देंगे। एक बेहतर तरीका CGImageSourceCreateThumbnailAtIndexयह है कि पहले पूरी तरह से डिकोड किए बिना छवि को आकार देने के लिए उपयोग किया जाए।

यदि आपके पास उस छवि का पथ है जिसे आप आकार देना चाहते हैं, तो आप इसका उपयोग कर सकते हैं:

- (void)resizeImageAtPath:(NSString *)imagePath {
    // Create the image source (from path)
    CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef) [NSURL fileURLWithPath:imagePath], NULL);

    // To create image source from UIImage, use this
    // NSData* pngData =  UIImagePNGRepresentation(image);
    // CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)pngData, NULL);

    // Create thumbnail options
    CFDictionaryRef options = (__bridge CFDictionaryRef) @{
            (id) kCGImageSourceCreateThumbnailWithTransform : @YES,
            (id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
            (id) kCGImageSourceThumbnailMaxPixelSize : @(640)
    };
    // Generate the thumbnail
    CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options); 
    CFRelease(src);
    // Write the thumbnail at path
    CGImageWriteToFile(thumbnail, imagePath);
}

अधिक जानकारी यहाँ


धन्यवाद, यह समाधान एक आकर्षण की तरह काम करता है), क्या आप अन्य फ़ाइल स्वरूपों को जानते हैं जो CGImageSourceछवियों और पीडीएफ़ के अलावा समर्थन करता है ?
ऋषि ४४४

धन्यवाद। मैं एक एनालॉग की तलाश में था inSampleSizeजिसका उपयोग एंड्रॉइड के डिकोडर द्वारा किया जाता है। और यह एकमात्र उत्तर है जो एक छवि को स्मृति कुशल तरीके से नीचे स्केल करने का एक तरीका प्रदान करता है।
स्टेन मॉट्स

मेरे पास भंडारण में फ़ाइलों के साथ सीधे काम करने के साथ बहुत अच्छे परिणाम थे, इन-मेमोरी छवियों के साथ भी काम करता है लेकिन जल्दी से नहीं (बड़ी छवि में लोड करने के लिए एक UIImage फिर पैमाने पर)।
केंडल हेल्मसटेटर गेलनर

शेयर एक्सटेंशन में काम नहीं करता है। ऐप अभी भी बहुत बड़ी छवि के साथ दुर्घटनाग्रस्त हो रहा है।
जॉर्ज

18

पहलू अनुपात को खोने के बिना छवियों को स्केल करने का सबसे अच्छा तरीका है (यानी सामान को खींचे बिना) इस पद्धति का उपयोग करना है:

//to scale images without changing aspect ratio
+ (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)newSize {

    float width = newSize.width;
    float height = newSize.height;

    UIGraphicsBeginImageContext(newSize);
    CGRect rect = CGRectMake(0, 0, width, height);

    float widthRatio = image.size.width / width;
    float heightRatio = image.size.height / height;
    float divisor = widthRatio > heightRatio ? widthRatio : heightRatio;

    width = image.size.width / divisor;
    height = image.size.height / divisor;

    rect.size.width  = width;
    rect.size.height = height;

    //indent in case of width or height difference
    float offset = (width - height) / 2;
    if (offset > 0) {
        rect.origin.y = offset;
    }
    else {
        rect.origin.x = -offset;
    }

    [image drawInRect: rect];

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

    return smallImage;

}

इस विधि को अपनी उपयोगिता वर्ग में शामिल करें ताकि आप इसे अपने पूरे प्रोजेक्ट में उपयोग कर सकें, और इसे इस तरह एक्सेस कर सकें:

xyzImageView.image = [Utility scaleImage:yourUIImage toSize:xyzImageView.frame.size];

यह विधि पहलू अनुपात को बनाए रखते हुए स्केलिंग का ध्यान रखती है। यह छवि को संकेत भी जोड़ता है यदि स्केल की गई छवि में ऊंचाई (या इसके विपरीत) से अधिक चौड़ाई है।


8

यदि आपके पास सर्वर पर नियंत्रण है, तो मैं दृढ़ता से इमेज सर्वर साइड को इमेजमैजिक के साथ बदलने की सिफारिश करूंगा । बड़ी छवियों को डाउनलोड करना और फोन पर उनका आकार बदलना कई कीमती संसाधनों - बैंडविड्थ, बैटरी और मेमोरी की बर्बादी है। जिनमें से सभी फोन पर दुर्लभ हैं।


2
FTFQ: "मेरा एप्लिकेशन नेटवर्क से छवि फ़ाइलों का एक सेट डाउनलोड कर रहा है,"
Rog

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

6

मैंने स्विफ्ट में इमेज स्केलिंग के लिए एक अंतिम समाधान विकसित किया।

आप इसका उपयोग छवि को आकार, पहलू भरने या पहलू निर्दिष्ट आकार को भरने के लिए आकार बदलने के लिए कर सकते हैं।

आप छवि को केंद्र या चार किनारों और चार कोनों में से किसी से संरेखित कर सकते हैं।

और साथ ही आप अतिरिक्त स्थान को ट्रिम कर सकते हैं जो जोड़ा जाता है यदि मूल छवि और लक्ष्य आकार के पहलू अनुपात समान नहीं हैं।

enum UIImageAlignment {
    case Center, Left, Top, Right, Bottom, TopLeft, BottomRight, BottomLeft, TopRight
}

enum UIImageScaleMode {
    case Fill,
    AspectFill,
    AspectFit(UIImageAlignment)
}

extension UIImage {
    func scaleImage(width width: CGFloat? = nil, height: CGFloat? = nil, scaleMode: UIImageScaleMode = .AspectFit(.Center), trim: Bool = false) -> UIImage {
        let preWidthScale = width.map { $0 / size.width }
        let preHeightScale = height.map { $0 / size.height }
        var widthScale = preWidthScale ?? preHeightScale ?? 1
        var heightScale = preHeightScale ?? widthScale
        switch scaleMode {
        case .AspectFit(_):
            let scale = min(widthScale, heightScale)
            widthScale = scale
            heightScale = scale
        case .AspectFill:
            let scale = max(widthScale, heightScale)
            widthScale = scale
            heightScale = scale
        default:
            break
        }
        let newWidth = size.width * widthScale
        let newHeight = size.height * heightScale
        let canvasWidth = trim ? newWidth : (width ?? newWidth)
        let canvasHeight = trim ? newHeight : (height ?? newHeight)
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(canvasWidth, canvasHeight), false, 0)

        var originX: CGFloat = 0
        var originY: CGFloat = 0
        switch scaleMode {
        case .AspectFit(let alignment):
            switch alignment {
            case .Center:
                originX = (canvasWidth - newWidth) / 2
                originY = (canvasHeight - newHeight) / 2
            case .Top:
                originX = (canvasWidth - newWidth) / 2
            case .Left:
                originY = (canvasHeight - newHeight) / 2
            case .Bottom:
                originX = (canvasWidth - newWidth) / 2
                originY = canvasHeight - newHeight
            case .Right:
                originX = canvasWidth - newWidth
                originY = (canvasHeight - newHeight) / 2
            case .TopLeft:
                break
            case .TopRight:
                originX = canvasWidth - newWidth
            case .BottomLeft:
                originY = canvasHeight - newHeight
            case .BottomRight:
                originX = canvasWidth - newWidth
                originY = canvasHeight - newHeight
            }
        default:
            break
        }
        self.drawInRect(CGRectMake(originX, originY, newWidth, newHeight))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

नीचे इस समाधान को लागू करने के उदाहरण हैं।

ग्रे आयत है लक्ष्य साइट छवि को आकार दिया जाएगा। हल्के नीले आयत में नीले वृत्त छवि है (मैंने हलकों का उपयोग किया क्योंकि यह देखने में आसान है कि कब इसे संरक्षण के पहलू के बिना बढ़ाया जाए)। हल्के नारंगी रंग के निशान उन क्षेत्रों को चिन्हित करते हैं जिन्हें यदि आप पास करते हैं तो इसे ट्रिम कर दिया जाएगा trim: true

स्केलिंग से पहले और बाद में पहलू फिट :

पहलू 1 फिट (पहले) पहलू फिट 1 (बाद)

पहलू फिट का एक और उदाहरण :

पहलू फिट 2 (पहले) पहलू फिट 2 (बाद)

शीर्ष संरेखण के साथ पहलू फिट :

पहलू फिट 3 (पहले) पहलू फिट 3 (बाद)

पहलू भरण :

पहलू भरण (पहले) पहलू भरण (बाद)

भरें :

भरें (पहले) भरें (बाद में)

मैंने अपने उदाहरणों में अपसंस्कृति का उपयोग किया क्योंकि यह प्रदर्शित करना सरल है लेकिन समाधान भी प्रश्न के अनुसार डाउनस्कलिंग के लिए काम करता है।

JPEG संपीड़न के लिए आपको इसका उपयोग करना चाहिए:

let compressionQuality: CGFloat = 0.75 // adjust to change JPEG quality
if let data = UIImageJPEGRepresentation(image, compressionQuality) {
  // ...
}

आप Xcode खेल के मैदान के साथ मेरे जिस्ट की जाँच कर सकते हैं ।


3

स्विफ्ट 3 के लिए, नीचे दिया गया कोड पहलू अनुपात को ध्यान में रखते हुए चित्र बनाता है। आप Apple के प्रलेखन में ImageContext के बारे में अधिक पढ़ सकते हैं :

extension UIImage {
    class func resizeImage(image: UIImage, newHeight: CGFloat) -> UIImage {
        let scale = newHeight / image.size.height
        let newWidth = image.size.width * scale
        UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
        image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage!
    }
}

इसका उपयोग करने के लिए, कॉल resizeImage()विधि:

UIImage.resizeImage(image: yourImageName, newHeight: yourImageNewHeight)

2

आप आवश्यक आकार में छवि को स्केल करने के लिए इस कोड का उपयोग कर सकते हैं।

+ (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)newSize
{
    CGSize actSize = image.size;
    float scale = actSize.width/actSize.height;

    if (scale < 1) {
        newSize.height = newSize.width/scale;
    } 
    else {
        newSize.width = newSize.height*scale;
    }

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

    return newImage;
}

2

इस सत्र के अनुसार, आईओएस मेमोरी डीप डाइव , हमारे पास ImageIOछवियों को डाउनस्केल करने के लिए बेहतर उपयोग था ।

UIImageडाउनस्केल छवियों का उपयोग करने का बुरा ।

  • स्मृति में मूल छवि को विघटित करेगा
  • आंतरिक समन्वय स्थान परिवर्तन महंगे हैं

उपयोग ImageIO

  • ImageIO मैमोरी डिटेलिंग के बिना इमेज साइज और मेटाडेटा की जानकारी पढ़ सकता है।

  • ImageIO केवल आकार की छवि की कीमत पर छवियों का आकार बदल सकता है।

स्मृति में छवि के बारे में

  • मेमोरी का उपयोग छवियों के आयामों से संबंधित है, न कि फ़ाइल के आकार से।
  • UIGraphicsBeginImageContextWithOptionsहमेशा SRGBरेंडरिंग-प्रारूप का उपयोग करता है , जो प्रति पिक्सेल 4 बाइट्स का उपयोग करता है ।
  • एक छवि में load -> decode -> render3 चरण होते हैं।
  • UIImage आकार और आकार बदलने के लिए महंगा है

निम्नलिखित छवि के लिए, यदि आप उपयोग करते हैं UIGraphicsBeginImageContextWithOptions तो हमें केवल एक छवि को लोड करने के लिए 590KB की आवश्यकता होती है, जबकि 2048 pixels x 1536 pixels x 4 bytes per pixelडिकोडिंग के दौरान हमें = 10MB की आवश्यकता होती है यहां छवि विवरण दर्ज करें

जबकि UIGraphicsImageRenderer, iOS 10 में पेश किया गया, स्वचालित रूप से iOS12 में सबसे अच्छा ग्राफिक प्रारूप चुन लेगा। इसका मतलब है, आप की जगह स्मृति के 75% को बचाने कर सकते हैं UIGraphicsBeginImageContextWithOptionsके साथ UIGraphicsImageRendererअगर आप SRGB जरूरत नहीं है।

यह मेमोरी में iOS छवियों के बारे में मेरा लेख है

func resize(url: NSURL, maxPixelSize: Int) -> CGImage? {
    let imgSource = CGImageSourceCreateWithURL(url, nil)
    guard let imageSource = imgSource else {
        return nil
    }

    var scaledImage: CGImage?
    let options: [NSString: Any] = [
            // The maximum width and height in pixels of a thumbnail.
            kCGImageSourceThumbnailMaxPixelSize: maxPixelSize,
            kCGImageSourceCreateThumbnailFromImageAlways: true,
            // Should include kCGImageSourceCreateThumbnailWithTransform: true in the options dictionary. Otherwise, the image result will appear rotated when an image is taken from camera in the portrait orientation.
            kCGImageSourceCreateThumbnailWithTransform: true
    ]
    scaledImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options as CFDictionary)

    return scaledImage
}


let filePath = Bundle.main.path(forResource:"large_leaves_70mp", ofType: "jpg")

let url = NSURL(fileURLWithPath: filePath ?? "")

let image = resize(url: url, maxPixelSize: 600)

या

// Downsampling large images for display at smaller size
func downsample(imageAt imageURL: URL, to pointSize: CGSize, scale: CGFloat) -> UIImage {
    let imageSourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
    let imageSource = CGImageSourceCreateWithURL(imageURL as CFURL, imageSourceOptions)!
    let maxDimensionInPixels = max(pointSize.width, pointSize.height) * scale
    let downsampleOptions =
        [kCGImageSourceCreateThumbnailFromImageAlways: true,
        kCGImageSourceShouldCacheImmediately: true,
        // Should include kCGImageSourceCreateThumbnailWithTransform: true in the options dictionary. Otherwise, the image result will appear rotated when an image is taken from camera in the portrait orientation.
        kCGImageSourceCreateThumbnailWithTransform: true,
        kCGImageSourceThumbnailMaxPixelSize: maxDimensionInPixels] as CFDictionary
    let downsampledImage =
        CGImageSourceCreateThumbnailAtIndex(imageSource, 0, downsampleOptions)!
    return UIImage(cgImage: downsampledImage)
}

1

एक समस्या जो रेटिना डिस्प्ले पर हो सकती है वह यह है कि छवि का पैमाना ImageCapture या तो द्वारा निर्धारित किया गया है। ऊपर दिए गए कार्यों का आकार परिवर्तन नहीं होगा। इन मामलों में रिसाइज़ ठीक से काम नहीं करेगा।

नीचे दिए गए कोड में, स्केल को 1 पर सेट किया गया है (स्केल नहीं किया गया है) और लौटी हुई छवि में वह आकार है जिसकी आप अपेक्षा करेंगे। यह UIGraphicsBeginImageContextWithOptionsकॉल में किया जाता है ।

-(UIImage *)resizeImage :(UIImage *)theImage :(CGSize)theNewSize {
    UIGraphicsBeginImageContextWithOptions(theNewSize, NO, 1.0);
    [theImage drawInRect:CGRectMake(0, 0, theNewSize.width, theNewSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

1

यहाँ उत्तरों के क्रम में जोड़ना, लेकिन मैं एक समाधान के लिए गया हूं जो आयामों के बजाय फ़ाइल आकार द्वारा आकार बदलता है।

यह छवि के आयाम और गुणवत्ता दोनों को कम कर देगा जब तक कि यह आपके दिए गए आकार तक नहीं पहुंचता।

func compressTo(toSizeInMB size: Double) -> UIImage? {
    let bytes = size * 1024 * 1024
    let sizeInBytes = Int(bytes)
    var needCompress:Bool = true
    var imgData:Data?
    var compressingValue:CGFloat = 1.0

    while (needCompress) {

        if let resizedImage = scaleImage(byMultiplicationFactorOf: compressingValue), let data: Data = UIImageJPEGRepresentation(resizedImage, compressingValue) {

            if data.count < sizeInBytes || compressingValue < 0.1 {
                needCompress = false
                imgData = data
            } else {
                compressingValue -= 0.1
            }
        }
    }

    if let data = imgData {
        print("Finished with compression value of: \(compressingValue)")
        return UIImage(data: data)
    }
    return nil
}

private func scaleImage(byMultiplicationFactorOf factor: CGFloat) -> UIImage? {
    let size = CGSize(width: self.size.width*factor, height: self.size.height*factor)
    UIGraphicsBeginImageContext(size)
    draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
    if let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext() {
        UIGraphicsEndImageContext()
        return newImage;
    }
    return nil
}

आकार उत्तर द्वारा स्केलिंग का श्रेय


1

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

func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage? {

    let scale = newWidth / image.size.width
    let newHeight = CGFloat(200.0)
    UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
    image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage
}

0

मैंने ब्रैड तकनीक का उपयोग करके एक scaleToFitWidthविधि तैयार की, UIImage+Extensionsयदि वह किसी के लिए उपयोगी हो ...

-(UIImage *)scaleToFitWidth:(CGFloat)width
{
    CGFloat ratio = width / self.size.width;
    CGFloat height = self.size.height * ratio;

    NSLog(@"W:%f H:%f",width,height);

    UIGraphicsBeginImageContext(CGSizeMake(width, height));
    [self drawInRect:CGRectMake(0.0f,0.0f,width,height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

फिर आपको जहां भी पसंद हो

#import "UIImage+Extensions.h"

UIImage *newImage = [image scaleToFitWidth:100.0f];

यह भी ध्यान देने योग्य है कि आप इसे एक UIView+Extensionsवर्ग में नीचे ले जा सकते हैं यदि आप एक UIView से चित्र प्रस्तुत करना चाहते हैं


0

मैं सिर्फ कोको स्विफ्ट प्रोग्रामर के लिए उस सवाल का जवाब देना चाहता था। यह फ़ंक्शन नए आकार के साथ NSImage लौटाता है। आप उस फंक्शन को इस तरह से इस्तेमाल कर सकते हैं।

        let sizeChangedImage = changeImageSize(image, ratio: 2)






 // changes image size

    func changeImageSize (image: NSImage, ratio: CGFloat) -> NSImage   {

    // getting the current image size
    let w = image.size.width
    let h = image.size.height

    // calculating new size
    let w_new = w / ratio 
    let h_new = h / ratio 

    // creating size constant
    let newSize = CGSizeMake(w_new ,h_new)

    //creating rect
    let rect  = NSMakeRect(0, 0, w_new, h_new)

    // creating a image context with new size
    let newImage = NSImage.init(size:newSize)



    newImage.lockFocus()

        // drawing image with new size in context
        image.drawInRect(rect)

    newImage.unlockFocus()


    return newImage

}

0

यदि आप चित्र दस्तावेज़ निर्देशिका में हैं, तो इस URL एक्सटेंशन को जोड़ें :

extension URL {
    func compressedImageURL(quality: CGFloat = 0.3) throws -> URL? {
        let imageData = try Data(contentsOf: self)
        debugPrint("Image file size before compression: \(imageData.count) bytes")

        let compressedURL = NSURL.fileURL(withPath: NSTemporaryDirectory() + NSUUID().uuidString + ".jpg")

        guard let actualImage = UIImage(data: imageData) else { return nil }
        guard let compressedImageData = UIImageJPEGRepresentation(actualImage, quality) else {
            return nil
        }
        debugPrint("Image file size after compression: \(compressedImageData.count) bytes")

        do {
            try compressedImageData.write(to: compressedURL)
            return compressedURL
        } catch {
            return nil
        }
    }
}

उपयोग:

guard let localImageURL = URL(string: "< LocalImagePath.jpg >") else {
    return
}

//Here you will get URL of compressed image
guard let compressedImageURL = try localImageURL.compressedImageURL() else {
    return
}

debugPrint("compressedImageURL: \(compressedImageURL.absoluteString)")

नोट: - अपने स्थानीय jpg छवि पथ के साथ <LocalImagePath.jpg> बदलें।


-1

अगर किसी को अभी भी बेहतर विकल्प की तलाश है

-(UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)targetSize {


    UIImage *sourceImage = image;
    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;
        else
            scaleFactor = heightFactor;

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


    // this is actually the interesting part:

    UIGraphicsBeginImageContext(targetSize);

    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width  = scaledWidth;
    thumbnailRect.size.height = scaledHeight;

    [sourceImage drawInRect:thumbnailRect];

    newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

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


    return newImage ;

}

-1
- (UIImage *)resizeImage:(UIImage*)image newSize:(CGSize)newSize {
    CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
    CGImageRef imageRef = image.CGImage;

    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
    CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height);

    CGContextConcatCTM(context, flipVertical);
    CGContextDrawImage(context, newRect, imageRef);

    CGImageRef newImageRef = CGBitmapContextCreateImage(context);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];

    CGImageRelease(newImageRef);
    UIGraphicsEndImageContext();

    return newImage;
}

कृपया, अपने उत्तर में कोड का कम से कम कुछ स्पष्टीकरण प्रदान करें। और उत्तर देने योग्य बनाने के लिए उत्तर संपादक का उपयोग करके कोड को प्रारूपित भी करें।
xpereta

-2

एक छवि का आकार बदलने के लिए, मेरे पास इस फ़ंक्शन का उपयोग करके ड्राअइनरक्ट के अनुसार बेहतर (चित्रमय) परिणाम हैं:

- (UIImage*) reduceImageSize:(UIImage*) pImage newwidth:(float) pWidth
{
    float lScale = pWidth / pImage.size.width;
    CGImageRef cgImage = pImage.CGImage;
    UIImage   *lResult = [UIImage imageWithCGImage:cgImage scale:lScale
                            orientation:UIImageOrientationRight];
    return lResult;
}

पहलू अनुपात का स्वचालित रूप से ध्यान रखा जाता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.