BradLarson / GPUImage

An open source iOS framework for GPU-based image and video processing
http://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework
BSD 3-Clause "New" or "Revised" License
20.23k stars 4.61k forks source link

Issues with Image Orientation #242

Open DaffyDuck opened 12 years ago

DaffyDuck commented 12 years ago

I'm using iOS 5 with user interface orientation locked to Landscape Right. I'm having two issues with displaying and saving images:

1) Setting the output orientation to LandscapeRight causes the images to appear upside down on the screen. I have to set it to LandscapeLeft for it to appear correctly. Below is the code I'm using:

// Set up view GPUImageView *imageView = [[GPUImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 426, 320)]; imageView.autoresizingMask = false; [self.view insertSubview:imageView atIndex:0];

// Set up filter filter = [[GPUImageRGBFilter alloc] init]; [filter addTarget:imageView]; [filter prepareForImageCapture];

// Set up camera and start view finder camera = [[GPUImageStillCamera alloc] init]; camera.outputImageOrientation = UIInterfaceOrientationLandscapeLeft; [camera addTarget:filter]; [camera startCameraCapture];

2) While setting landscape mode to Left fixes the on-screen issue, saving images to disk always appear in portrait orientation with this code:

[camera capturePhotoAsJPEGProcessedUpToFilter:filter withCompletionHandler:^(NSData processedJPEG, NSError error){ ALAssetsLibrary library = [[ALAssetsLibrary alloc] init]; [library writeImageDataToSavedPhotosAlbum:processedJPEG metadata:nil completionBlock:^(NSURL assetURL, NSError *error2) { .... }); }]; }];

If I set the output orientation to UIInterfaceOrientationPortrait, the images save to disk correctly, but show in the viewfinder as a portrait within a landscape (black on the sides).

Any suggestions as to what I might be doing wrong or if there is a bug I'm hitting?

DaffyDuck commented 12 years ago

I've reviewed this issue in more detail and I believe it is a bug in the API. It is reproducible if you take the "SimplePhotoFilter" example and change the orientation function as follows:

Then, set "stillCamera.outputImageOrientation = UIInterfaceOrientationLandscapeRight". If you do, the image will be opposite down on the screen. If you change it to "UIInterfaceOrientationLandscapeLeft", then the screen will be correct, but it will be saved in the wrong orientation. When viewed in the Photo application, it will show as portrait when it should be landscape, and visa versa.

DaffyDuck commented 12 years ago

I wrote a work-around solution for #2 that overrides the image information on saving items to disk such as:

    NSMutableDictionary *tiffMetadata = [[NSMutableDictionary alloc] init];
    [tiffMetadata setObject:[NSNumber numberWithInt:<Number> forKey:(NSString*)kCGImagePropertyTIFFOrientation];
    NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init];
    [metadata setObject:tiffMetadata forKey:(NSString*)kCGImagePropertyTIFFDictionary];

    [library writeImageDataToSavedPhotosAlbum:processedJPEG metadata:metadata completionBlock:^(NSURL *assetURL, NSError *error2) {

The value for -Number- allows you to force the orientation the item is saved at. I wrote a conversion table that, depending on the orientation of the device, sets the value.

DaffyDuck commented 12 years ago

The conversion table I used for LandscapeRight iOS5 app is as follows:

-(int)getTranslatedOrientation:(UIDeviceOrientation) orientation { switch(orientation) { case UIDeviceOrientationPortrait: return 6; // Right, top case UIDeviceOrientationLandscapeRight: return 3; // Bottom, right case UIDeviceOrientationPortraitUpsideDown: return 8; // Left, bottom case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: case UIDeviceOrientationUnknown: case UIDeviceOrientationLandscapeLeft: return 1; // Top, left } }

With the following used as the value: [self getTranslatedOrientation: [[UIDevice currentDevice] orientation]]]

ItsTipTop commented 11 years ago

for me it work

NSMutableDictionary temp = [[NSMutableDictionary alloc] initWithDictionary:stillCamera.currentCaptureMetadata]; [temp setObject:[NSNumber numberWithInt:1] forKey:@"Orientation"]; //your value [library writeImageToSavedPhotosAlbum:PortraitImage.CGImage metadata:temp completionBlock:^(NSURL assetURL, NSError *error2)

just change value orientation in current metadata

phildow commented 11 years ago

Left and right are both reversed. The workaround is to map the orientations to values that work correctly with the view and filter:

- (UIInterfaceOrientation) orientationForVideo:(UIInterfaceOrientation)orientation
{
  // Fixes a bug with current GPUImageView where UIInterfaceOrientationLandscapeRight|Left
  // are reversed and produce an upside down image

  if (orientation == UIInterfaceOrientationLandscapeRight) {
    return UIInterfaceOrientationLandscapeLeft;
  } else if (orientation == UIInterfaceOrientationLandscapeLeft) {
    return UIInterfaceOrientationLandscapeRight;
  } else {
    return orientation;
  }
}
SushilSharma12 commented 9 years ago

Hello Phildow, I'm having issue with GPUImageStillCamera. When I turn OFF device rotation and capture image in landscape mode with GPUImageStillCamera, captured image in camera roll is not in portrait mode. It is in landscape mode and when I rotate device in landscape mode , image rotates in portrait upsideDown. I'm trying to resolve issue from last four days but still cannot resolve this. Can you please help me out ?