UIImagePickerController कैमरा दृश्य iOS 8 पर अजीब तरीके से घूमता है(चित्र)




objective-c ios8 (8)

इस मुद्दे को iOS 8.1 में कॉन्टेक्ट्स ऐप के साथ टेस्ट किया गया है। ठीक काम करता है।

लेकिन एक और मुद्दा मुझे मिला,

  1. संपर्क ऐप पर जाएं
  2. अपने डिवाइस को ऐसे रखें जैसे आईपैड कैमरा ज़मीन से लगा हो।
  3. संपर्क जोड़ें -> फ़ोटो लें

फेसअप ओरिएंटेशन के साथ इसे 2 3 बार टेस्ट करें, जैसा कि आप ऊपर अपलोड की गई तस्वीरों में देख सकते हैं, कैमरा व्यू अजीब तरीके से फिर से घूमने लगेगा।

मेरे पास एक बहुत ही सरल अनुप्रयोग है: - सभी अभिविन्यासों को स्क्रीन पर केवल एक बटन के साथ अनुमति दी जाती है - बटन एक UIImagePickerController दिखाता है (एक तस्वीर लेने के लिए) - Xcode 5 और SDK 7 के साथ बनाएँ

IOS 8 पर , UIImagePickerController का कैमरा सही ढंग से दिखाई दे रहा है कि मैं लैंडस्केप में हूं या पोर्ट्रेट में, लेकिन जब मैं डिवाइस को घुमाता हूं, तो मुझे कैमरा व्यू 90 डिग्री से घुमाया गया, यहां एक उदाहरण है:

  1. मेरे पास पोर्ट्रेट में मेरा ऐप है
  2. मैं उस बटन को धक्का देता हूं जो मुझे UIImagePickerController दिखाता है
  3. मैं कैमरे के दृश्य में हूं और मैं लैंडस्केप मोड में जाता हूं, यहां मुझे वही मिलता है:

दृश्य परिदृश्य में है, लेकिन कैमरा 90 डिग्री तक घुमाया जाता है

क्या किसी और को पहले से ही यह मुद्दा मिला है?

पुनश्च: और अगर मैं एक फोटो (फिर से परिदृश्य में) लेता हूं, तो फोटो सही तरीके से लिया गया है और अब सही ढंग से प्रदर्शित किया गया है:

संपादित करें

बग आईपैड 8.1 पर चलने वाले मेरे आईपैड पर तय किया गया है, लेकिन आईओएस 8.1 रिलीज नोट्स में उस बग से संबंधित कुछ भी नहीं दिखता है: https://developer.apple.com/library/content/releasenotes/General/RN-iOSSDK-8.1/

IOS 8 के पुराने संस्करणों के लिए प्रस्तावित फ़िक्सेस के लिए धन्यवाद !


इस समस्या को ठीक करने के लिए Apple इंतजार नहीं कर सकता ...

- (void)viewWillAppear:(BOOL)animated
{
  ...
  if (iPad & iOS 8)
  {
    switch (device_orientation)
    {
      case UIDeviceOrientationPortraitUpsideDown: self.cameraViewTransform = CGAffineTransformMakeRotation(DEGREES_RADIANS(180)); break;
      case UIDeviceOrientationLandscapeLeft: self.cameraViewTransform = CGAffineTransformMakeRotation(DEGREES_RADIANS(90)); break;
      case UIDeviceOrientationLandscapeRight: self.cameraViewTransform = CGAffineTransformMakeRotation(DEGREES_RADIANS(-90)); break;
      default: break;
    }
  }
}

मुझे इस मुद्दे के लिए एक और बहुत अच्छा समाधान मिला है जिसका मैं वर्तमान में उपयोग कर रहा हूं। UIImagePickerController का उपयोग करके छवि को कैप्चर करने के बाद आपको बस इस विधि के लिए एक छवि के रूप में छवि को पास करना होगा। यह iOS के सभी वर्जन के लिए और कैमरा के पोर्ट्रेट और लैंडस्केप ओरिएंटेशन दोनों के लिए भी अच्छा है। यह UIImageOrientaiton का उपयोग करके छवि की EXIF ​​संपत्ति के लिए जाँच करता है और अभिविन्यास के मूल्य के अनुरूप होता है, यह छवि को रूपांतरित और परिमार्जित करता है जिससे आपको उसी वापसी छवि मिलेगी जो आपके कैमरा दृश्य अभिविन्यास के समान है।

यहाँ मैंने अधिकतम 3000 रिज़ॉल्यूशन रखे हैं ताकि रेटिना उपकरणों का उपयोग करते समय छवि गुणवत्ता विशेष रूप से खराब न हो लेकिन आप अपनी आवश्यकता के अनुसार इसके रिज़ॉल्यूशन को बदल सकते हैं।

// उद्देश्य सी कोड:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info;
{
     UIImage *imagePicked = [info valueForKey:UIImagePickerControllerOriginalImage];

     imagePicked = [self scaleAndRotateImage:imagePicked];

     [[self delegate] sendImage:imagePicked];
     [self.imagePicker dismissViewControllerAnimated:YES completion:nil];    
}

- (UIImage *) scaleAndRotateImage: (UIImage *)image
{
    int kMaxResolution = 3000; // Or whatever

    CGImageRef imgRef = image.CGImage;

    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);

    CGAffineTransform transform = CGAffineTransformIdentity;
    CGRect bounds = CGRectMake(0, 0, width, height);
    if (width > kMaxResolution || height > kMaxResolution) {
        CGFloat ratio = width/height;
        if (ratio > 1) {
            bounds.size.width = kMaxResolution;
            bounds.size.height = bounds.size.width / ratio;
        }
        else {
            bounds.size.height = kMaxResolution;
            bounds.size.width = bounds.size.height * ratio;
        }
    }

    CGFloat scaleRatio = bounds.size.width / width;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef),      CGImageGetHeight(imgRef));
    CGFloat boundHeight;
    UIImageOrientation orient = image.imageOrientation;
    switch(orient)
    {
        case UIImageOrientationUp: //EXIF = 1
             transform = CGAffineTransformIdentity;
             break;

        case UIImageOrientationUpMirrored: //EXIF = 2
             transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
             transform = CGAffineTransformScale(transform, -1.0, 1.0);
             break;

        case UIImageOrientationDown: //EXIF = 3
             transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
             transform = CGAffineTransformRotate(transform, M_PI);
             break;

        case UIImageOrientationDownMirrored: //EXIF = 4
             transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
             transform = CGAffineTransformScale(transform, 1.0, -1.0);
             break;

        case UIImageOrientationLeftMirrored: //EXIF = 5
             boundHeight = bounds.size.height;
             bounds.size.height = bounds.size.width;
             bounds.size.width = boundHeight;
             transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
             transform = CGAffineTransformScale(transform, -1.0, 1.0);
             transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
             break;

        case UIImageOrientationLeft: //EXIF = 6
             boundHeight = bounds.size.height;
             bounds.size.height = bounds.size.width;
             bounds.size.width = boundHeight;
             transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
             transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
             break;

        case UIImageOrientationRightMirrored: //EXIF = 7
             boundHeight = bounds.size.height;
             bounds.size.height = bounds.size.width;
             bounds.size.width = boundHeight;
             transform = CGAffineTransformMakeScale(-1.0, 1.0);
             transform = CGAffineTransformRotate(transform, M_PI / 2.0);
             break;

        case UIImageOrientationRight: //EXIF = 8
             boundHeight = bounds.size.height;
             bounds.size.height = bounds.size.width;
             bounds.size.width = boundHeight;
             transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        default:
            [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
     }

     UIGraphicsBeginImageContext(bounds.size);

     CGContextRef context = UIGraphicsGetCurrentContext();

     if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft)
     {
         CGContextScaleCTM(context, -scaleRatio, scaleRatio);
         CGContextTranslateCTM(context, -height, 0);
     }
     else {
         CGContextScaleCTM(context, scaleRatio, -scaleRatio);
         CGContextTranslateCTM(context, 0, -height);
     }

     CGContextConcatCTM(context, transform);

     CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
     UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();

     return imageCopy;
}

// स्विफ्ट 4.0 कोड:

func scaleAndRotateImage(image: UIImage, MaxResolution iIntMaxResolution: Int) -> UIImage {
        let kMaxResolution = iIntMaxResolution
        let imgRef = image.cgImage!
        let width: CGFloat = CGFloat(imgRef.width)
        let height: CGFloat = CGFloat(imgRef.height)
        var transform = CGAffineTransform.identity
        var bounds = CGRect.init(x: 0, y: 0, width: width, height: height)

        if Int(width) > kMaxResolution || Int(height) > kMaxResolution {
            let ratio: CGFloat = width / height
            if ratio > 1 {
                bounds.size.width = CGFloat(kMaxResolution)
                bounds.size.height = bounds.size.width / ratio
            }
            else {
                bounds.size.height = CGFloat(kMaxResolution)
                bounds.size.width = bounds.size.height * ratio
            }
        }
        let scaleRatio: CGFloat = bounds.size.width / width
        let imageSize = CGSize.init(width: CGFloat(imgRef.width), height: CGFloat(imgRef.height))

        var boundHeight: CGFloat
        let orient = image.imageOrientation
        // The output below is limited by 1 KB.
        // Please Sign Up (Free!) to remove this limitation.

        switch orient {
        case .up:
            //EXIF = 1
            transform = CGAffineTransform.identity
        case .upMirrored:
            //EXIF = 2
            transform = CGAffineTransform.init(translationX: imageSize.width, y: 0.0)
            transform = transform.scaledBy(x: -1.0, y: 1.0)

        case .down:
            //EXIF = 3
            transform = CGAffineTransform.init(translationX: imageSize.width, y: imageSize.height)
            transform = transform.rotated(by: CGFloat(Double.pi / 2))

        case .downMirrored:
            //EXIF = 4
            transform = CGAffineTransform.init(translationX: 0.0, y: imageSize.height)
            transform = transform.scaledBy(x: 1.0, y: -1.0)
        case .leftMirrored:
            //EXIF = 5
            boundHeight = bounds.size.height
            bounds.size.height = bounds.size.width
            bounds.size.width = boundHeight
            transform = CGAffineTransform.init(translationX: imageSize.height, y: imageSize.width)

            transform = transform.scaledBy(x: -1.0, y: 1.0)
            transform = transform.rotated(by: CGFloat(Double.pi / 2) / 2.0)
            break

        default: print("Error in processing image")
        }

        UIGraphicsBeginImageContext(bounds.size)
        let context = UIGraphicsGetCurrentContext()
        if orient == .right || orient == .left {
            context?.scaleBy(x: -scaleRatio, y: scaleRatio)
            context?.translateBy(x: -height, y: 0)
        }
        else {
            context?.scaleBy(x: scaleRatio, y: -scaleRatio)
            context?.translateBy(x: 0, y: -height)
        }
        context?.concatenate(transform)
        context?.draw(imgRef, in: CGRect.init(x: 0, y: 0, width: width, height: height))
        let imageCopy = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return imageCopy!
    }

मुझे इस मुद्दे को हल करने के लिए एक आसान और सटीक पैच मिला। UIImagePickerController प्रस्तुत करने से पहले निम्नलिखित कोड जोड़ें:

if (iOS8_Device)
{
            if([[UIDevice currentDevice]orientation] == UIDeviceOrientationFaceUp)
            {
                if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft)
                {
                    [[UIDevice currentDevice]setValue:[NSNumber numberWithInteger:UIDeviceOrientationLandscapeRight] forKey:@"orientation"];
                }
                else
                {
                    [[UIDevice currentDevice]setValue:[NSNumber numberWithInteger:UIDeviceOrientationLandscapeLeft] forKey:@"orientation"];
                }
            }
}

इसके अलावा आपको UIImagePickerController को उप-वर्ग करने की आवश्यकता है और इसे बेहतर तरीके से काम करने के लिए नीचे दी गई विधि को ओवरराइड करें।

- (BOOL)shouldAutorotate
{
    [super shouldAutorotate];
    return NO;
}

उपरोक्त कोड का उपयोग करने के बाद यह दोनों लैंडस्केप ओरिएंटेशन के लिए अच्छी तरह से काम करेगा और ओरिएंटेशन को UIDeviceOrientationFaceUace मोड में नहीं बदला जाएगा।


मुझे यही मुद्दा मिला। मैंने iOS 7.1.2 और iOS 8 दोनों पर परीक्षण किया है। अब तक, यह केवल iOS 8 के साथ iPad डिवाइस पर हुआ है। इसलिए मैं कोड का पालन करके इसे अस्थायी रूप से ठीक करता हूं:

// In my app, I subclass UIImagePickerController and code my own control buttons
// showsCameraControls = NO;
- (void)viewWillAppear:(BOOL)animated
{
  [super viewWillAppear:animated];
  [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:@"orientation"];
}

यह अनुशंसित नहीं है क्योंकि यह presentingViewController के उन्मुखीकरण को गड़बड़ कर देगा।

क्या अभी तक Apple के कोई जवाब नहीं हैं?


मेरा मानना ​​है कि यह एक iOS 8 बग है जैसा कि हिटमे ने उल्लेख किया है। मैंने संपर्क ऐप के उदाहरण के संबंध में एक Apple टिकट दर्ज किया और इसकी एक खुली रडार प्रति यहां बनाई। http://openradar.appspot.com/18416803

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

प्रजनन करने कि प्रक्रिया:
1. संपर्क ऐप खोलें
2. iPad को लैंडस्केप मोड में घुमाएं
3. एक डेस्क पर फ्लैट करने के लिए आईपैड बिछाएं
4. नया संपर्क जोड़ें
5. फ़ोटो जोड़ें> फ़ोटो लें 6. iPad उठाएं

अपेक्षित परिणाम:
छवि कैप्चर दृश्यदर्शी पूर्ण स्क्रीन को लैंडस्केप मोड में उन्मुख प्रदर्शित करता है।

वास्तविक परिणाम:
इमेज कैप्चर व्यूफाइंडर 90 डिग्री घुमाया गया है और यह फुल स्क्रीन नहीं है।

संस्करण प्रभावित: iOS 8.0, 8.0.2, और 8.1।


मेरे पास एक ही मुद्दा था और मूल बातें वापस लेने और एक नई परियोजना बनाने के लिए जो वास्तव में काम करती थी .. मैंने इसे नीचे ट्रैक किया;

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    // Had forgot to call the following..
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

आशा करता हूँ की ये काम करेगा।


यह वह कोड है जिसका उपयोग मैंने अपने ऐप को ठीक करने के लिए किया था जो कि OpenCV कैमरा को परिदृश्य में घुमा रहा था यदि कैमरा फेस डेस्क स्थिति में डेस्क पर डिवाइस के साथ शुरू किया गया था। एप्लिकेशन को सही ढंग से काम करने के लिए कैमरे को पोर्ट्रेट मोड में मजबूर करने की आवश्यकता है।

- (BOOL)shouldAutorotate
 {
    [super shouldAutorotate];
    return NO;
 }

-(void)viewDidAppear:(BOOL)animated
{

    [super viewDidAppear: animated];

    if([[UIDevice currentDevice]orientation] == UIDeviceOrientationFaceUp)
        {
            if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft)
            {
                [[UIDevice currentDevice]setValue:[NSNumber numberWithInteger:UIDeviceOrientationPortrait] forKey:@"orientation"];
            }
            else
            {
                [[UIDevice currentDevice]setValue:[NSNumber numberWithInteger:UIDeviceOrientationPortrait] forKey:@"orientation"];
            }
        }
}




screen-rotation