2

カメラから画像をキャプチャし、その画像を次のビューに設定するためのiPhoneアプリを作成しました。しかし、問題は画像が回転することです。つまり、風景画像はポトライトになり、プロトライト画像は風景になります。私は多くのコードを参照しましたが、解決策を得ることができませんでした。

私のコードは:

- (void)btnCapturePressed
{
 if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
        {

            picker=[[UIImagePickerController alloc] init];
            picker.delegate=self;

            [picker setAllowsEditing:YES];

            picker.sourceType=UIImagePickerControllerSourceTypeCamera;
            //[self.navigationController pushViewController:(UIViewController *)ipc animated:YES];
            [self presentModalViewController:picker animated:YES];
            [picker release];
      }
}

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

            imgView = [[UIImageView alloc] initWithImage:imageToScale];

            [picker presentModalViewController:cropper animated:YES];
}

リンクも参照しました。同じ問題がありますが、解決策を見つけることができませんでした。

私を助けてください。

ありがとう。

4

4 に答える 4

4

そのため、画像の取得時にデバイスの向きを保存し、パラメータとして以下のメソッドに渡します。ここでは、メソッドに任意の名前を付けて、パラメータを渡します。orientation

switch (orientation) {
            case UIDeviceOrientationPortrait:
                [featureLayer setAffineTransform:CGAffineTransformMakeRotation(DegreesToRadians(0.))];
                break;
            case UIDeviceOrientationPortraitUpsideDown:
                [featureLayer setAffineTransform:CGAffineTransformMakeRotation(DegreesToRadians(180.))];
                break;
            case UIDeviceOrientationLandscapeLeft:
                [featureLayer setAffineTransform:CGAffineTransformMakeRotation(DegreesToRadians(90.))];
                break;
            case UIDeviceOrientationLandscapeRight:
                [featureLayer setAffineTransform:CGAffineTransformMakeRotation(DegreesToRadians(-90.))];
                break;
            case UIDeviceOrientationFaceUp:
            case UIDeviceOrientationFaceDown:
            default:
                break; // leave the layer in its last known orientation
        }

ここで使用したマクロDegreesToRadians()は次のとおりです

static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};

これは間違いなく機能します。

ハッピーコーディング:)

編集

上記のコードがうまく機能しない場合は、これを使用してください

@interface UIImage (RotationMethods)
- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees;
@end

@implementation UIImage (RotationMethods)

- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees 
{   
    // calculate the size of the rotated view's containing box for our drawing space
    UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.size.width, self.size.height)];
    CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees));
    rotatedViewBox.transform = t;
    CGSize rotatedSize = rotatedViewBox.frame.size;

    // Create the bitmap context
    UIGraphicsBeginImageContext(rotatedSize);
    CGContextRef bitmap = UIGraphicsGetCurrentContext();

    // Move the origin to the middle of the image so we will rotate and scale around the center.
    CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);

    //   // Rotate the image context
    CGContextRotateCTM(bitmap, DegreesToRadians(degrees));

    // Now, draw the rotated/scaled image into the context
    CGContextScaleCTM(bitmap, 1.0, -1.0);
    CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), [self CGImage]);

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;

}
@end

次に、上記の関数を以下のように呼び出します

switch (orientation) {
        case UIDeviceOrientationPortrait:
            image = [image imageRotatedByDegrees:0];
            break;
        case UIDeviceOrientationPortraitUpsideDown:
            image = [image imageRotatedByDegrees:180];
            break;
        case UIDeviceOrientationLandscapeLeft:
            image = [image imageRotatedByDegrees:-90];
            break;
        case UIDeviceOrientationLandscapeRight:
            image = [image imageRotatedByDegrees:90];
            break;
        case UIDeviceOrientationFaceUp:
        case UIDeviceOrientationFaceDown:
        default:
            break; // leave the layer in its last known orientation
    }   

画像が必要な向きになっていない場合は、上記imageRotatedByDegreesのすべての引数に90を追加します(つまり、0の場合は0 + 90になります)。または必要に応じて追加します。

編集1

UIDeviceOrientation curDeviceOrientation = [[UIDevice currentDevice] orientation];
于 2012-07-03T07:38:00.747 に答える
3

私はこの問題に苦労していましたが、はるかに簡単な解決策を見つけました:

  AVCaptureConnection *vc = [self.snapper connectionWithMediaType:AVMediaTypeVideo];

  // THIS IS THE KEY LINE!!!!!!!!!!!!!!!!!!!!!
  [vc setVideoOrientation:[self interfaceToVideoOrientation]];

  [self.snapper captureStillImageAsynchronouslyFromConnection:vc
                                            completionHandler:
   ^(CMSampleBufferRef buf, NSError *err) {
     NSData* data = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:buf];
     UIImage* im = [UIImage imageWithData:data];
     // Do something with the image.
  }];


- (AVCaptureVideoOrientation)interfaceToVideoOrientation
{
  switch ([UIApplication sharedApplication].statusBarOrientation)
  {
    case UIInterfaceOrientationPortrait:
      return AVCaptureVideoOrientationPortrait;
    case UIInterfaceOrientationPortraitUpsideDown:
      return AVCaptureVideoOrientationPortraitUpsideDown;
    case UIInterfaceOrientationLandscapeRight:
      return AVCaptureVideoOrientationLandscapeRight;
    case UIInterfaceOrientationLandscapeLeft:
      return AVCaptureVideoOrientationLandscapeLeft;
    default:
      return AVCaptureVideoOrientationPortrait;
  }
}

キャプチャの前にビデオの向きを設定すると、画像の向きが間違ってしまう問題が修正されました。

于 2015-03-24T06:19:10.993 に答える
1

私はアップルのフォーラム( https://discussions.apple.com/thread/1537011?start=0&tstart=0 )での議論を参照し、次の解決策を見つけました。それは私にとって完璧に機能しました。コピーして貼り付けるだけで、宝石のように機能しました。

-(UIImage *) scaleAndRotateImage(UIImage *)image
{
 int kMaxResolution = 320; // 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;
}
于 2013-01-03T10:00:48.933 に答える
1

私も同じ問題を抱えていて、これが私を助けてくれました。それがあなたにも役立つことを願っています。この問題を修正するのに2分かかりました。http://xcodetipss.blogspot.com/2012/04/image-rotated-when-taken-from-camera.html

于 2014-06-02T09:37:15.047 に答える