अपलोड करने के बाद iOS UIImagePickerController परिणाम छवि अभिविन्यास


332

मैं आईओएस 3.1.3 iPhone पर अपने iPhone एप्लिकेशन का परीक्षण कर रहा हूं। मैं एक का उपयोग कर एक छवि का चयन / कैप्चर कर रहा हूं UIImagePickerController:

UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[imagePicker setDelegate:self];
[self.navigationController presentModalViewController:imagePicker animated:YES];
[imagePicker release];



- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
    imageView.image = self.image;
    [self.navigationController dismissModalViewControllerAnimated:YES];
    submitButton.enabled = YES;
}

फिर मैं कुछ बिंदुओं पर एएसआई कक्षाओं का उपयोग करके इसे अपने वेब सर्वर पर भेजता हूं:

ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://example.com/myscript.php"]];
[request setDelegate:self];
[request setStringEncoding:NSUTF8StringEncoding];
[request setShouldContinueWhenAppEntersBackground:YES];
//other post keys/values
[request setFile:UIImageJPEGRepresentation(self.image, 100.0f) withFileName:[NSString stringWithFormat:@"%d.jpg", [[NSDate date] timeIntervalSinceNow]] andContentType:@"image/jpg" forKey:@"imageFile"];
[request startAsynchronous];

समस्या: जब मैं इसे लैंडस्केप करते समय आईफोन के साथ एक तस्वीर लेता हूं, तो छवि सर्वर पर अपलोड हो जाती है और इसे ऐसे देखा जाता है जैसे आप उम्मीद करेंगे। जब चित्र में फोन पकड़े हुए चित्र लेते हैं, तो छवि को अपलोड किया जाता है और देखा जाता है क्योंकि इसे 90 डिग्री घुमाया गया था।

मेरा आवेदन केवल पोर्ट्रेट मोड (अप्सडाउन और नियमित) में काम करने के लिए सेट है।

मैं अपलोड करने के बाद छवि को हमेशा सही अभिविन्यास कैसे दिखा सकता हूं?

छवि UIImageView (सीधे चित्र लेने के बाद) में प्रदर्शित होने के रूप में सही प्रतीत होती है, लेकिन सर्वर पर देखना अन्यथा कहता है।

जवाबों:


513

ए के UIImageपास एक संपत्ति है imageOrientation, जो UIImageViewअन्य UIImageउपभोक्ताओं को कच्ची छवि डेटा को घुमाने के लिए निर्देश देती है । एक अच्छा मौका है कि इस झंडे को अपलोड की गई jpeg छवि में exif डेटा पर सहेजा जा रहा है, लेकिन आप जिस प्रोग्राम को देखने के लिए उपयोग करते हैं, वह उस ध्वज का सम्मान नहीं कर रहा है।

UIImageअपलोड होने पर ठीक से प्रदर्शित करने के लिए, आप इस तरह से एक श्रेणी का उपयोग कर सकते हैं:

UIImage + fixOrientation.h

@interface UIImage (fixOrientation)

- (UIImage *)fixOrientation;

@end

UIImage + fixOrientation.m

@implementation UIImage (fixOrientation)

- (UIImage *)fixOrientation {

    // No-op if the orientation is already correct
    if (self.imageOrientation == UIImageOrientationUp) return self;

    // We need to calculate the proper transformation to make the image upright.
    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
    CGAffineTransform transform = CGAffineTransformIdentity;

    switch (self.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;

        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, self.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        case UIImageOrientationUp:
        case UIImageOrientationUpMirrored:
            break;
    }

    switch (self.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;

        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        case UIImageOrientationUp:
        case UIImageOrientationDown:
        case UIImageOrientationLeft:
        case UIImageOrientationRight:
            break;
    }

    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
                                             CGImageGetBitsPerComponent(self.CGImage), 0,
                                             CGImageGetColorSpace(self.CGImage),
                                             CGImageGetBitmapInfo(self.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (self.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
            break;

        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
            break;
    }

    // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return img;
}

@end

9
धन्यवाद, सही काम किया। एक श्रेणी का इस्तेमाल कभी नहीं किया या अब तक उन्हें समझा नहीं!
जेम्स

1
@Anomie मेरे लिए यह समझाना कठिन है कि आपने मुझे कितना खुश किया। आपके उत्तर ने मेरा दिन बचा लिया। आपका बहुत बहुत धन्यवाद।
डार्कहॉर्स ग्रूपर

3
मैं एक ही कोशिश की, सही काम करता है, लेकिन यह 32 सेकंड * 2448 संकल्प छवियों को घुमाने के लिए appx 2-3 सेकंड ले रहा है। तो कृपया बेहतर संस्करण का सुझाव दें।
लक्ष्मी लाल मेनारिया

3
मैं stackoverflow.com/questions/8915630/… को बेहतर उत्तर मानता हूँ
pojomx

2
यहां इस समस्या का एक और समाधान अभी भी है (यह काफी समान है) जिसमें वास्तव में चल रही एक लंबी चर्चा शामिल है।
ग्लीमोन नोव

239

मुझे पता चला कि एक बहुत आसान है:

- (UIImage *)normalizedImage {
    if (self.imageOrientation == UIImageOrientationUp) return self; 

    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
    [self drawInRect:(CGRect){0, 0, self.size}];
    UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return normalizedImage;
}

BTW: @ Anomie का कोड ध्यान scaleमें नहीं रखता है, इसलिए 2x छवियों के लिए काम नहीं करेगा।


आप इसे कोड में कैसे उपयोग करते हैं? मेरे पास यह एक है: UIImageJPEGRepresentation (छवि, 90); जहां छवि एक UIImage है
Dejell

2
@Odelya इस विधि को अपने UIImage श्रेणी में जोड़ें, फिर [image normalizedImage] पर कॉल करें। या selfअपनी UIImage ऑब्जेक्ट के साथ बदलकर सीधे विधि के कोड का उपयोग करें ।
AN0

1
@ a0 विधि में लगभग एक सेकंड का समय लगता है। क्या इसमें सुधार करने का कोई तरीका है?
देजेल

1
इसके लिए धन्यवाद। मेरे परीक्षणों से ऐसा लगता है कि यह विधि चुने हुए उत्तर की तुलना में थोड़ी तेज है, मेरे iphone4 पर 20% की तरह कुछ है।
क्रिसबेन

7
इस समस्या का एक और समाधान यहाँ है और साथ ही साथ जो कुछ चल रहा है उसकी लम्बी व्याख्या भी।
ग्लीमोन

118

यहाँ @ a0 द्वारा उत्तर का एक स्विफ्ट संस्करण है:

func normalizedImage() -> UIImage {

  if (self.imageOrientation == UIImageOrientation.Up) { 
      return self;
  }

  UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale);
  let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
  self.drawInRect(rect)

  let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
  UIGraphicsEndImageContext();
  return normalizedImage;
}

एक सामान्य कार्य में भी:

func fixOrientation(img:UIImage) -> UIImage {

  if (img.imageOrientation == UIImageOrientation.Up) { 
      return img;
  }

  UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale);
  let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
  img.drawInRect(rect)

  let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
  UIGraphicsEndImageContext();
  return normalizedImage;

}

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

func fixOrientation(img: UIImage) -> UIImage {
    if (img.imageOrientation == .up) {
        return img
    }

    UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale)
    let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
    img.draw(in: rect)

    let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()

    return normalizedImage
}

7
दुर्लभ है कि आप सबसे अच्छा जवाब के लिए नीचे करने के लिए सभी तरह स्क्रॉल करने की आवश्यकता है। +1!
सूडो मेक

मुझे कहाँ तय करना चाहिए मेरे पास एक सेवइमेज फंक्शन है, क्या मुझे इसका उपयोग करना चाहिए या मेरी इमेजहार्ड.इमेज पर?
एलेक्स

यदि आप ऊपर दिए गए अधिक सामान्य फ़ंक्शन का उपयोग करना चाहते हैं, तो हाँ आप इसे अपने saveImage फ़ंक्शन में उपयोग कर सकते हैं। बस अपनी UIImage ऑब्जेक्ट को ठीक करें और यह आपके द्वारा इसमें दिए गए UIImage के सही रूप से उन्मुख संस्करण को लौटाएगा।
प्राज्ञ

1
स्विफ्ट 3 संस्करण के लिए धन्यवाद
Shadros

41

कैमरा से छवि कैप्चर करते समय अभिविन्यास समस्या के लिए स्विफ्ट 3.1 का समाधान।

मैंने जेक और मेटल हार्ट द्वारा दिए गए समाधान को अपडेट किया है

UIImage एक्सटेंशन

//MARK:- Image Orientation fix

extension UIImage {

    func fixOrientation() -> UIImage {

        // No-op if the orientation is already correct
        if ( self.imageOrientation == UIImageOrientation.up ) {
            return self;
        }

        // We need to calculate the proper transformation to make the image upright.
        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
        var transform: CGAffineTransform = CGAffineTransform.identity

        if ( self.imageOrientation == UIImageOrientation.down || self.imageOrientation == UIImageOrientation.downMirrored ) {
            transform = transform.translatedBy(x: self.size.width, y: self.size.height)
            transform = transform.rotated(by: CGFloat(Double.pi))
        }

        if ( self.imageOrientation == UIImageOrientation.left || self.imageOrientation == UIImageOrientation.leftMirrored ) {
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.rotated(by: CGFloat(Double.pi / 2.0))
        }

        if ( self.imageOrientation == UIImageOrientation.right || self.imageOrientation == UIImageOrientation.rightMirrored ) {
            transform = transform.translatedBy(x: 0, y: self.size.height);
            transform = transform.rotated(by: CGFloat(-Double.pi / 2.0));
        }

        if ( self.imageOrientation == UIImageOrientation.upMirrored || self.imageOrientation == UIImageOrientation.downMirrored ) {
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)
        }

        if ( self.imageOrientation == UIImageOrientation.leftMirrored || self.imageOrientation == UIImageOrientation.rightMirrored ) {
            transform = transform.translatedBy(x: self.size.height, y: 0);
            transform = transform.scaledBy(x: -1, y: 1);
        }

        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        let ctx: CGContext = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height),
                                                      bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0,
                                                      space: self.cgImage!.colorSpace!,
                                                      bitmapInfo: self.cgImage!.bitmapInfo.rawValue)!;

        ctx.concatenate(transform)

        if ( self.imageOrientation == UIImageOrientation.left ||
            self.imageOrientation == UIImageOrientation.leftMirrored ||
            self.imageOrientation == UIImageOrientation.right ||
            self.imageOrientation == UIImageOrientation.rightMirrored ) {
            ctx.draw(self.cgImage!, in: CGRect(x: 0,y: 0,width: self.size.height,height: self.size.width))
        } else {
            ctx.draw(self.cgImage!, in: CGRect(x: 0,y: 0,width: self.size.width,height: self.size.height))
        }

        // And now we just create a new UIImage from the drawing context and return it
        return UIImage(cgImage: ctx.makeImage()!)
    }
}

स्विफ्ट 2.0

//MARK:- Image Orientation fix

extension UIImage {

    func fixOrientation() -> UIImage {

        // No-op if the orientation is already correct
        if ( self.imageOrientation == UIImageOrientation.Up ) {
            return self;
        }

        // We need to calculate the proper transformation to make the image upright.
        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
        var transform: CGAffineTransform = CGAffineTransformIdentity

        if ( self.imageOrientation == UIImageOrientation.Down || self.imageOrientation == UIImageOrientation.DownMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
        }

        if ( self.imageOrientation == UIImageOrientation.Left || self.imageOrientation == UIImageOrientation.LeftMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
        }

        if ( self.imageOrientation == UIImageOrientation.Right || self.imageOrientation == UIImageOrientation.RightMirrored ) {
            transform = CGAffineTransformTranslate(transform, 0, self.size.height);
            transform = CGAffineTransformRotate(transform,  CGFloat(-M_PI_2));
        }

        if ( self.imageOrientation == UIImageOrientation.UpMirrored || self.imageOrientation == UIImageOrientation.DownMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformScale(transform, -1, 1)
        }

        if ( self.imageOrientation == UIImageOrientation.LeftMirrored || self.imageOrientation == UIImageOrientation.RightMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
        }

        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        let ctx: CGContextRef = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
            CGImageGetBitsPerComponent(self.CGImage), 0,
            CGImageGetColorSpace(self.CGImage),
            CGImageGetBitmapInfo(self.CGImage).rawValue)!;

        CGContextConcatCTM(ctx, transform)

        if ( self.imageOrientation == UIImageOrientation.Left ||
            self.imageOrientation == UIImageOrientation.LeftMirrored ||
            self.imageOrientation == UIImageOrientation.Right ||
            self.imageOrientation == UIImageOrientation.RightMirrored ) {
                CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
        } else {
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
        }

        // And now we just create a new UIImage from the drawing context and return it
        return UIImage(CGImage: CGBitmapContextCreateImage(ctx)!)
    }
}

इस UIImage एक्सटेंशन का उपयोग अपने कोड में करें:

चलो ठीक करें

इस तरह की छवि पिकर के अपने प्रतिनिधि तरीकों में इसे रखें

स्विफ्ट 3.1

//MARK: Image Picker Delegates
    func imagePickerController(
        _ picker: UIImagePickerController,
        didFinishPickingMediaWithInfo info: [String : Any]){
        let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
        profileImg.contentMode = .scaleAspectFill
        let fixOrientationImage=chosenImage.fixOrientation()
        profileImg.image = fixOrientationImage

        dismiss(animated: true, completion: nil)
    }

स्विफ्ट 2.0

//MARK: Image Picker Delegates
    func imagePickerController(
        picker: UIImagePickerController,
        didFinishPickingMediaWithInfo info: [String : AnyObject])
    {
        let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
        profileImg.contentMode = .ScaleAspectFill
        **//Fix the image orientation**
         let fixOrientationImage=chosenImage.fixOrientation()
        profileImg.image = fixOrientationImage

        dismissViewControllerAnimated(true, completion: nil)
    }

3
धन्यवाद, इससे मुझे बहुत मदद मिली।
Darkndream

मेरे पास एक ViewController है, मैं इसे वहां कैसे डालूं?
applecrusher

अधिक विशेष रूप से, मैं इसे वहां कैसे डाल सकता हूं, और मुझे इस पद्धति को कॉल करने की आवश्यकता कहां है?
21

यही काम है। लेकिन मुझे आश्चर्य है कि कोई भी दृष्टिकोण है जो सीजी से संबंधित एपीआई को कॉल करने से बच सकता है, क्योंकि इससे बड़ी मात्रा में मेमोरी आवंटन होता है। यह केवल तब जारी किया जाएगा जब हम UIImage को बनाए नहीं रखेंगे।
टोनी फंग चोई फंग

1
यह iOS 10 तक ठीक काम कर रहा था। iOS 11 में यह प्रदर्शन करने के बाद मुझे बदले में एक काली छवि मिल रही है। मैंने हालांकि एक छोटा सा बदलाव (M_PI को Double.pi से बदल दिया है) किया है। मैं स्विफ्ट 3.2 के साथ एक्सकोड 9 का उपयोग कर रहा हूं।
महबूब मोरशेड

25

स्विफ्ट में;)

अद्यतन स्विफ्ट 3.0: डी

func sFunc_imageFixOrientation(img:UIImage) -> UIImage {


    // No-op if the orientation is already correct
    if (img.imageOrientation == UIImageOrientation.up) {
        return img;
    }
    // We need to calculate the proper transformation to make the image upright.
    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
    var transform:CGAffineTransform = CGAffineTransform.identity

    if (img.imageOrientation == UIImageOrientation.down
        || img.imageOrientation == UIImageOrientation.downMirrored) {

        transform = transform.translatedBy(x: img.size.width, y: img.size.height)
        transform = transform.rotated(by: CGFloat(M_PI))
    }

    if (img.imageOrientation == UIImageOrientation.left
        || img.imageOrientation == UIImageOrientation.leftMirrored) {

        transform = transform.translatedBy(x: img.size.width, y: 0)
        transform = transform.rotated(by: CGFloat(M_PI_2))
    }

    if (img.imageOrientation == UIImageOrientation.right
        || img.imageOrientation == UIImageOrientation.rightMirrored) {

        transform = transform.translatedBy(x: 0, y: img.size.height);
        transform = transform.rotated(by: CGFloat(-M_PI_2));
    }

    if (img.imageOrientation == UIImageOrientation.upMirrored
        || img.imageOrientation == UIImageOrientation.downMirrored) {

        transform = transform.translatedBy(x: img.size.width, y: 0)
        transform = transform.scaledBy(x: -1, y: 1)
    }

    if (img.imageOrientation == UIImageOrientation.leftMirrored
        || img.imageOrientation == UIImageOrientation.rightMirrored) {

        transform = transform.translatedBy(x: img.size.height, y: 0);
        transform = transform.scaledBy(x: -1, y: 1);
    }


    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    let ctx:CGContext = CGContext(data: nil, width: Int(img.size.width), height: Int(img.size.height),
                                  bitsPerComponent: img.cgImage!.bitsPerComponent, bytesPerRow: 0,
                                  space: img.cgImage!.colorSpace!,
                                  bitmapInfo: img.cgImage!.bitmapInfo.rawValue)!

    ctx.concatenate(transform)


    if (img.imageOrientation == UIImageOrientation.left
        || img.imageOrientation == UIImageOrientation.leftMirrored
        || img.imageOrientation == UIImageOrientation.right
        || img.imageOrientation == UIImageOrientation.rightMirrored
        ) {


        ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.height,height:img.size.width))

    } else {
        ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.width,height:img.size.height))
    }


    // And now we just create a new UIImage from the drawing context
    let cgimg:CGImage = ctx.makeImage()!
    let imgEnd:UIImage = UIImage(cgImage: cgimg)

    return imgEnd
}

इस मुद्दे से जूझने और कई अन्य समाधानों की कोशिश करने के बाद, यह एक पूरी तरह से काम कर रहा था। अगर मैं वोट कर सकता तो +10 मैं कर सकता था। धन्यवाद। :)
सरनोद

@ MetalHeart2003 इस विधि से MASSIVELY मेरी छवि का फ़ाइल आकार बढ़ाता है, मेरा 200kb से 4mb तक चला गया, क्या इसे रोकने का कोई तरीका है?
टिमविंग

2
@ यह ऐसा लगता है जैसे आप एक संकुचित छवि के साथ शुरू कर रहे हैं। लेकिन यह विधि बिना किसी संपीड़न के घुमाई गई छवि को फिर से बनाती है। आप बाद में UIImageJPEGRepresentation () के साथ बिटमैप छवि पुनः प्राप्त कर सकते हैं
रिचर्ड

16

स्विफ्ट 4.x / 5.0 के @an0समाधान का संस्करण :

extension UIImage {
    func upOrientationImage() -> UIImage? {
        switch imageOrientation {
        case .up:
            return self
        default:
            UIGraphicsBeginImageContextWithOptions(size, false, scale)
            draw(in: CGRect(origin: .zero, size: size))
            let result = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return result
        }
    }
}

1
धन्यवाद। मैं पूरी तरह से काम करता हूं। बहुत कम जवाब मिला।
विनायक भोर


12

मैंने अपने एप्लिकेशन को डिज़ाइन करते समय इस पृष्ठ का उपयोग किया था जो चित्र लेता है और मैंने पाया कि निम्न विधि अभिविन्यास को सही करेगी और पिछले मेमोरी की तुलना में कम मेमोरी और प्रोसेसर का उपयोग करेगी:

CGImageRef cgRef = image.CGImage;
image = [[UIImage alloc] initWithCGImage:cgRef scale:1.0 orientation:UIImageOrientationUp];

यह मूल रूप से सिर्फ एक नई अभिविन्यास के साथ वास्तविक छवि डेटा को फिर से खोल देता है। मैं @ a0 के कोड का उपयोग कर रहा था, लेकिन यह मेमोरी में एक नई छवि बनाता है जो एक 3264x2448 छवि पर कर लगा सकता है जो आपको कैमरे से मिल सकता है।


1
मैंने iPhone 5s पर iOS 7.1 के साथ इस उत्तर का परीक्षण किया, लेकिन यह काम नहीं किया, जिसमें विंडोज़ मशीनें [MS-Paint, Win photo Viewer] और UIImageView ने मूल से 90 डिग्री अभिविन्यास के साथ छवि दिखाई! ध्यान दें कि डिफ़ॉल्ट कैमरा टच बटन के साथ ली गई छवियां, वॉल्यूम ऊपर नहीं।
जावद अल शेख

3
ऐसा लगता है कि यह सिर्फ अभिविन्यास ध्वज को बदलता है ... वास्तविक बिट्स को घुमाने की जरूरत है
हैम्स्टर्ड

10

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

UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.allowsEditing = YES;
// set delegate and present controller

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIImage *photo = [info valueForKey:UIImagePickerControllerEditedImage];
    // do whatever
}

संपादन सक्षम करने से उपयोगकर्ता "फ़ोटो का उपयोग करें" टैप करने से पहले छवि को आकार बदलने और स्थानांतरित करने की अनुमति देता है


दुर्भाग्य से यह समाधान क्षैतिज रूप से छवि को फ्लिप नहीं करता है, यहां तक ​​कि संपादन की अनुमति भी देता है।
राजा-जादूगर

4
काम करता है, लेकिन उपयोगकर्ता को वर्ग के लिए छवियों को क्रॉप करने के लिए मजबूर करता है जब तक कि आप चर फसल के आकार की अनुमति देने के लिए बहुत अधिक कोड नहीं जोड़ना चाहते हैं
user3000868

6

यह जो मैंने अभिविन्यास मुद्दे को ठीक करने के लिए पाया है

UIImage *initialImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
NSData *data = UIImagePNGRepresentation(self.initialImage);

UIImage *tempImage = [UIImage imageWithData:data];
UIImage *fixedOrientationImage = [UIImage imageWithCGImage:tempImage.CGImage
                                     scale:initialImage.scale
                               orientation:self.initialImage.imageOrientation];
initialImage = fixedOrientationImage;

संपादित करें:

UIImage *initialImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
NSData *data = UIImagePNGRepresentation(self.initialImage);

initialImage = [UIImage imageWithCGImage:[UIImage imageWithData:data].CGImage
                                                     scale:initialImage.scale
                                               orientation:self.initialImage.imageOrientation];

2
PNG में छवि के बीच छवि में बहुत अधिक रूपांतरण, रास्ता बहुत महंगा है। @ a0 उत्तर बेहतर है।
lxcid

4

Sourabh Sharmaकोड की सफाई के साथ, स्विफ्ट 3.1 के अपडेट के आधार पर अपडेट करें ।

extension UIImage {
    func fixedOrientation() -> UIImage {
        if imageOrientation == .up { return self }

        var transform:CGAffineTransform = .identity
        switch imageOrientation {
        case .down, .downMirrored:
            transform = transform.translatedBy(x: size.width, y: size.height).rotated(by: .pi)
        case .left, .leftMirrored:
            transform = transform.translatedBy(x: size.width, y: 0).rotated(by: .pi/2)
        case .right, .rightMirrored:
            transform = transform.translatedBy(x: 0, y: size.height).rotated(by: -.pi/2)
        default: break
        }

        switch imageOrientation {
        case .upMirrored, .downMirrored:
            transform = transform.translatedBy(x: size.width, y: 0).scaledBy(x: -1, y: 1)
        case .leftMirrored, .rightMirrored:
            transform = transform.translatedBy(x: size.height, y: 0).scaledBy(x: -1, y: 1)
        default: break
        }

        let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height),
                                       bitsPerComponent: cgImage!.bitsPerComponent, bytesPerRow: 0,
                                       space: cgImage!.colorSpace!, bitmapInfo: cgImage!.bitmapInfo.rawValue)!
        ctx.concatenate(transform)

        switch imageOrientation {
        case .left, .leftMirrored, .right, .rightMirrored:
            ctx.draw(cgImage!, in: CGRect(x: 0, y: 0, width: size.height,height: size.width))
        default:
            ctx.draw(cgImage!, in: CGRect(x: 0, y: 0, width: size.width,height: size.height))
        }
        return UIImage(cgImage: ctx.makeImage()!)
    }
}

पिकर प्रतिनिधि विधि उदाहरण:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    guard let originalImage = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }
    let fixedImage = originalImage.fixedOrientation()
    // do your work
}

4

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

extension UIImage {
    static let rotatedOrentations: [UIImage.Orientation] = [.left, .leftMirrored, .right, .rightMirrored]

    func normalizedImage() -> UIImage {
        if imageOrientation == .up {
            return self
        }

        let image = self.cgImage!
        let swapOrientation = UIImage.rotatedOrentations.contains(imageOrientation)
        let width = swapOrientation ? image.height : image.width
        let height = swapOrientation ? image.width : image.height
        let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: image.bitsPerComponent, bytesPerRow: image.bytesPerRow, space: image.colorSpace!, bitmapInfo: image.bitmapInfo.rawValue)!
        let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: CGFloat(height));
        context.concatenate(flipVertical)
        UIGraphicsPushContext(context)
        self.draw(at: .zero)
        UIGraphicsPopContext()

        return UIImage(cgImage: context.makeImage()!)
    }
}

3

यहां स्विफ्ट के लिए UIImage एक्सटेंशन दिया गया है:

extension UIImage {

    func fixOrientation() -> UIImage {

        // No-op if the orientation is already correct
        if ( self.imageOrientation == UIImageOrientation.Up ) {
            return self;
        }

        // We need to calculate the proper transformation to make the image upright.
        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
        var transform: CGAffineTransform = CGAffineTransformIdentity

        if ( self.imageOrientation == UIImageOrientation.Down || self.imageOrientation == UIImageOrientation.DownMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
        }

        if ( self.imageOrientation == UIImageOrientation.Left || self.imageOrientation == UIImageOrientation.LeftMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
        }

        if ( self.imageOrientation == UIImageOrientation.Right || self.imageOrientation == UIImageOrientation.RightMirrored ) {
            transform = CGAffineTransformTranslate(transform, 0, self.size.height);
            transform = CGAffineTransformRotate(transform,  CGFloat(-M_PI_2));
        }

        if ( self.imageOrientation == UIImageOrientation.UpMirrored || self.imageOrientation == UIImageOrientation.DownMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformScale(transform, -1, 1)
        }

        if ( self.imageOrientation == UIImageOrientation.LeftMirrored || self.imageOrientation == UIImageOrientation.RightMirrored ) {
            transform = CGAffineTransformTranslate(transform, self.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
        }

        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        var ctx: CGContextRef = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
            CGImageGetBitsPerComponent(self.CGImage), 0,
            CGImageGetColorSpace(self.CGImage),
            CGImageGetBitmapInfo(self.CGImage));

        CGContextConcatCTM(ctx, transform)

        if ( self.imageOrientation == UIImageOrientation.Left ||
            self.imageOrientation == UIImageOrientation.LeftMirrored ||
            self.imageOrientation == UIImageOrientation.Right ||
            self.imageOrientation == UIImageOrientation.RightMirrored ) {
                CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
        } else {
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
        }

        // And now we just create a new UIImage from the drawing context and return it
        return UIImage(CGImage: CGBitmapContextCreateImage(ctx))!
    }
}

MetalHeart2003 के पहले के काम के आधार पर ..


3

यहाँ स्विफ्ट 2 में UIImage एक्सटेंशन @Anomie द्वारा स्वीकृत उत्तर के आधार पर दिया गया है। यह क्लियर स्विच केस का उपयोग करता है। यह वैकल्पिक मूल्य CGBitmapContextCreateImage()को ध्यान में रखकर लौटाता है ।

extension UIImage {
    func rotateImageByOrientation() -> UIImage {
        // No-op if the orientation is already correct
        guard self.imageOrientation != .Up else {
            return self
        }

        // We need to calculate the proper transformation to make the image upright.
        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
        var transform = CGAffineTransformIdentity;

        switch (self.imageOrientation) {
        case .Down, .DownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))

        case .Left, .LeftMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))

        case .Right, .RightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, self.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))

        default:
            break
        }

        switch (self.imageOrientation) {
        case .UpMirrored, .DownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformScale(transform, -1, 1)

        case .LeftMirrored, .RightMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.height, 0)
            transform = CGAffineTransformScale(transform, -1, 1)

        default:
            break
        }

        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        let ctx = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
            CGImageGetBitsPerComponent(self.CGImage), 0,
            CGImageGetColorSpace(self.CGImage),
            CGImageGetBitmapInfo(self.CGImage).rawValue)
        CGContextConcatCTM(ctx, transform)
        switch (self.imageOrientation) {
        case .Left, .LeftMirrored, .Right, .RightMirrored:
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)

        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
        }

        // And now we just create a new UIImage from the drawing context
        if let cgImage = CGBitmapContextCreateImage(ctx) {
            return UIImage(CGImage: cgImage)
        } else {
            return self
        }
    }
}

3

मैंने इस मुद्दे को कैमरे से ली गई छवियों के साथ अनुभव किया है या कैमरा रोल में सहेजा है जो कैमरे से लिए गए हैं। सफारी ब्राउज़र से फोटो लाइब्रेरी में डाउनलोड की गई छवियाँ अपलोड होने पर घूमती नहीं हैं।

मैं अपलोड करने से पहले JPEG के रूप में छवि डेटा बनाकर इस समस्या को हल करने में सक्षम था।

let image = info[UIImagePickerControllerOriginalImage] as! UIImage        
let data = UIImageJPEGRepresentation(image, 1.0)

हम अब अपलोड करने के लिए डेटा का उपयोग कर सकते हैं और अपलोड के बाद छवि को घुमाया नहीं जाएगा।

उम्मीद है कि यह काम करेगा।


इतना अजीब है कि पीएनजी डेटा घूमता रहता है, लेकिन जेपीईजी डेटा का उपयोग करते समय रोटेशन ठीक हो जाता है।
user3344977

2

मैं इसे कोड की कुछ पंक्तियों के नीचे लिखकर प्राप्त करता हूं

extension UIImage {

    public func correctlyOrientedImage() -> UIImage {
        if self.imageOrientation == UIImage.Orientation.up {
            return self
        }

        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        let normalizedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!;
        UIGraphicsEndImageContext();

        return normalizedImage;
    }
}

0

अगर मैं समझता हूं, तो आप क्या करना चाहते हैं, यह UIImage के अभिविन्यास की अवहेलना है? यदि ऐसा है तो आप ऐसा कर सकते हैं: -

//image is your original image
image = [UIImage imageWithCGImage:[image CGImage]
                             scale:[image scale]
                       orientation: UIImageOrientationUp];

या स्विफ्ट में: -

image = UIImage(CGImage: image.CGImage!, scale: image.scale, orientation:.Up)

इसने मेरी फसल को हल कर दिया .. आशा है, यह वही है जो आप खोज रहे हैं ..


0

@ Jake1981 पर आधारित स्विफ्ट 3 संस्करण जिन्होंने इसे @ MetalHeart2003 से लिया है

extension UIImage {

    func fixOrientation() -> UIImage {

        // No-op if the orientation is already correct
        if ( self.imageOrientation == UIImageOrientation.up ) {
            return self;
        }

        // We need to calculate the proper transformation to make the image upright.
        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.

        var transform: CGAffineTransform = CGAffineTransform.identity

        if ( self.imageOrientation == UIImageOrientation.down || self.imageOrientation == UIImageOrientation.downMirrored ) {
            transform = transform.translatedBy(x: self.size.width, y: self.size.height)
            transform = transform.rotated(by: CGFloat(M_PI))
        }

        if ( self.imageOrientation == UIImageOrientation.left || self.imageOrientation == UIImageOrientation.leftMirrored ) {
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.rotated(by: CGFloat(M_PI_2))
        }

        if ( self.imageOrientation == UIImageOrientation.right || self.imageOrientation == UIImageOrientation.rightMirrored ) {
            transform = transform.translatedBy(x: 0, y: self.size.height);
            transform = transform.rotated(by: CGFloat(-M_PI_2));
        }

        if ( self.imageOrientation == UIImageOrientation.upMirrored || self.imageOrientation == UIImageOrientation.downMirrored ) {
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)
        }

        if ( self.imageOrientation == UIImageOrientation.leftMirrored || self.imageOrientation == UIImageOrientation.rightMirrored ) {
            transform = transform.translatedBy(x: self.size.height, y: 0);
            transform = transform.scaledBy(x: -1, y: 1);
        }

        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        let ctx: CGContext = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height),
                                       bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0,
                                       space: self.cgImage!.colorSpace!,
                                       bitmapInfo: self.cgImage!.bitmapInfo.rawValue)!
        ctx.concatenate(transform)

        if ( self.imageOrientation == UIImageOrientation.left ||
            self.imageOrientation == UIImageOrientation.leftMirrored ||
            self.imageOrientation == UIImageOrientation.right ||
            self.imageOrientation == UIImageOrientation.rightMirrored ) {

            ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: self.size.height, height: self.size.width))
        } else {
            ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        }

        // And now we just create a new UIImage from the drawing context and return it
        return UIImage(cgImage: ctx.makeImage()!)

    }
}

0
@an0, thanks for the answer!
The only thing is autoreleasepool: 

func fixOrientation(img: UIImage) -> UIImage? {

    let result: UIImage?
    if img.imageOrientation == .up {
        result = img
    } else {

        result = autoreleasepool { () -> UIImage? in
            UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale)
            let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
            img.draw(in: rect)

            let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            return normalizedImage
        }
    }

    return result
}

0

यहां आपकी छवि उन्मुखीकरण रिटर्न UIImage को स्वचालित रूप से ठीक करने के लिए स्विफ्ट-4.2 कोड है

func AutofixImageOrientation(_ image: UIImage)->UIImage {

    UIGraphicsBeginImageContext(image.size)

    image.draw(at: .zero)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    return newImage ?? image
}

0

मैंने इसे ज़ामरीन में बदल दिया:

private static UIImage FixImageOrientation(UIImage image)
    {
        if (image.Orientation == UIImageOrientation.Up)
        {
            return image;
        }

        var transform = CGAffineTransform.MakeIdentity();

        float pi = (float)Math.PI;

        switch (image.Orientation)
        {
            case UIImageOrientation.Down:
            case UIImageOrientation.DownMirrored:
                transform = CGAffineTransform.Translate(transform, image.Size.Width, image.Size.Height);
                transform = CGAffineTransform.Rotate(transform, pi);
                break;

            case UIImageOrientation.Left:
            case UIImageOrientation.LeftMirrored:
                transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
                transform = CGAffineTransform.Rotate(transform, pi / 2);
                break;

            case UIImageOrientation.Right:
            case UIImageOrientation.RightMirrored:
                transform = CGAffineTransform.Translate(transform, 0, image.Size.Height);
                transform = CGAffineTransform.Rotate(transform, -(pi / 2));
                break;
        }

        switch (image.Orientation)
        {
            case UIImageOrientation.UpMirrored:
            case UIImageOrientation.DownMirrored:
                transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
                transform = CGAffineTransform.Scale(transform, -1, 1);
                break;

            case UIImageOrientation.LeftMirrored:
            case UIImageOrientation.RightMirrored:
                transform = CGAffineTransform.Translate(transform, image.Size.Height, 0);
                transform = CGAffineTransform.Scale(transform, -1, 1);
                break;
        }

        var ctx = new CGBitmapContext(null, (nint)image.Size.Width, (nint)image.Size.Height, image.CGImage.BitsPerComponent,
            image.CGImage.BytesPerRow, image.CGImage.ColorSpace, image.CGImage.BitmapInfo);

        ctx.ConcatCTM(transform);

        switch (image.Orientation)
        {
            case UIImageOrientation.Left:
            case UIImageOrientation.LeftMirrored:
            case UIImageOrientation.Right:
            case UIImageOrientation.RightMirrored:
                ctx.DrawImage(new CGRect(0, 0, image.Size.Height, image.Size.Width), image.CGImage);
                break;

            default:
                ctx.DrawImage(new CGRect(0, 0, image.Size.Width, image.Size.Height), image.CGImage);
                break;
        }

        var cgimg = ctx.ToImage();
        var img = new UIImage(cgimg);

        ctx.Dispose();
        ctx = null;
        cgimg.Dispose();
        cgimg = null;

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