10

私のアプリで許可されている唯一の向きは横です。私はターゲットの下のプロジェクトのプロパティでこれを強制します > summery でポートレートのみを許可しますshouldAutorotateToInterfaceOrientation

問題は、携帯電話を横向き (横向き) に持って写真を撮ると、UI が縦向きモードのままで、写真が横向きで撮影されることです。

これは、横向きモードでは、縦長モードで取得する縦長の画像 (2448 x 3264) ではなく、3264 x 2448 の横長の画像を取得することを意味します。

次に、ユーザーは画像をトリミングできますが、画像を横向きモードで撮影すると、非常に醜い引き伸ばされた画像になります。境界線を追加したり、UI を横向きに切り替えたりすることはできません。

UIImagePickerController携帯電話を横向き (横向きモード)に持っていても、強制的に縦長の写真を撮る方法はありますか?

次の設定で初期化しUIImagePickerControllerます。

    imagePicker =[[UIImagePickerController alloc] init];
    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
    imagePicker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
    imagePicker.showsCameraControls = NO;
    imagePicker.modalPresentationStyle = UIModalPresentationFullScreen;
    imagePicker.wantsFullScreenLayout = YES;
    imagePicker.cameraViewTransform = CGAffineTransformScale(imagePicker.cameraViewTransform,CAMERA_TRANSFORM, CAMERA_TRANSFORM);
    imagePicker.navigationBarHidden = YES;
    imagePicker.toolbarHidden = YES;
    [self presentModalViewController:imagePicker animated:NO];
    imagePicker.cameraOverlayView = self.cameraOverlay;
    imagePicker.cameraFlashMode = UIImagePickerControllerCameraFlashModeOff;
4

1 に答える 1

17

imageOrientation フラグは、画像が撮影されたときにカメラが保持されている方向に応じて、UIImage に設定されます。これは読み取り専用フラグであり、ビューに画像を配置するときに iOS が画像を表示しようとする方向を決定します。

画像を表示する前に向きを確認し、それに応じて imageView を操作できます。同じサイズのビュー内に imageView が含まれていると仮定します...

- (void) imagePickerImage:(UIImage*)image
{
    if (image.imageOrientation == UIImageOrientationUp ) {
        self.imageView.bounds = CGRectMake
           (0, 0, self.view.bounds.size.height, self.view.bounds.size.width);
        self.imageView.transform = CGAffineTransformMakeRotation(M_PI/2);

    } else if (image.imageOrientation == UIImageOrientationDown) {
        self.imageView.bounds = CGRectMake
           (0, 0, self.view.bounds.size.height, self.view.bounds.size.width);
        self.imageView.transform = CGAffineTransformMakeRotation(-M_PI/2);
    }
    else {
        self.imageView.bounds = self.view.bounds;
        self.imageView.transform = CGAffineTransformIdentity;
    }
    self.imageView.image = image;
}

もう 1 つのオプションは、imageRep から新しいイメージを作成することです。これにより、方向情報が取り除かれます。

更新
iPhone の写真の本来のピクセル寸法は、撮影時の携帯電話の持ち方に関係なく、横長です。異なる方法で設定されるのは、向きのEXIFフラグのみです。EXIFフラグを変更することはできませんが、画像のビットマップ データを新しいビットマップ画像にコピーすることで取り除くことができます。こちらの回答もご覧ください。

EXIFデータを取り除き、ポートレートEXIFフラグを追加する方法を次に示します。新しい UIImage を作成し、作成時にEXIFフラグを設定しています。これを使用して、横長の画像に縦長のフラグを付けることができます ( UIImageOrientationRight)。

- (UIImage*)stripExif:(UIImage*)image
{
    CGImageRef cgImage = image.CGImage;
    UIImage* result = [UIImage imageWithCGImage:cgImage scale:1 
                                    orientation:UIImageOrientationRight];
    return result;
}

update 2
UIImage の imageOrientation プロパティを EXIF フラグとして参照するのは誤解を招きます。これには 2 つの理由があります。

(1) 画像メタデータは、辞書形式の構造で保存されます。その中には、EXIF を含む多数のサブ辞書を含めることができます。その他には、TIFF、IPTC、PNG などがあります。トップレベルのディクショナリには、タグの一般的なセットもあります。方向キーはEXIF セクションにはなく、TIFF および IPTC サブディクショナリ (存在する場合) にあり、最上位のキーとしても見つかります。画像メタデータ全体を指すときに EXIF という用語を使用する傾向がありますが、これは誤解を招くものです。

(2) 画像ファイルの方向メタデータは、Apple が UIImage.imageOrientation プロパティで使用するものとは異なる一連のフラグ規則を使用します。したがって、画像を正しく表示するためにこのプロパティを読み取る場合は注意が必要です。Apple は明らかに画像ファイルの向きのメタデータを使用して UIImage のプロパティを設定していますが、多少の変換が行われています。

 Orientation 

 Apple/UIImage.imageOrientation     Jpeg/File kCGImagePropertyOrientation

    UIImageOrientationUp    = 0  =  Landscape left  = 1
    UIImageOrientationDown  = 1  =  Landscape right = 3
    UIImageOrientationLeft  = 2  =  Portrait  down  = 8
    UIImageOrientationRight = 3  =  Portrait  up    = 6

これは「exif」回転フラグを示すページです。Apple の UIImage ドキュメント(定数セクション)と比較してください。特にApple のCGImageProperties_Referenceも参照してください。kCGImagePropertyOrientation

小さなプロジェクトをgithubにロードして、さまざまなUIImageメタデータの問題を記録しました

于 2013-01-23T23:25:53.257 に答える