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

GPUImage and iOS8 Photo Extension result not working with a full size image. #1724

Open valvoline opened 10 years ago

valvoline commented 10 years ago

I'm trying to use the GPUImage framework to make a simple Photo Extensions as follow:

- (BOOL)canHandleAdjustmentData:(PHAdjustmentData *)adjustmentData {
    return NO;
}

- (void)startContentEditingWithInput:(PHContentEditingInput *)contentEditingInput placeholderImage:(UIImage *)placeholderImage {
    self.input = contentEditingInput;
    _anImageView.image = self.input.displaySizeImage;

    filter = [[GPUImageSepiaFilter alloc] init];
    _anImageView.image = [filter imageByFilteringImage:self.input.displaySizeImage];
}

- (void)finishContentEditingWithCompletionHandler:(void (^)(PHContentEditingOutput *))completionHandler {
    dispatch_async(dispatch_get_main_queue(), ^{
        PHContentEditingOutput *contentEditingOutput = [[PHContentEditingOutput alloc] initWithContentEditingInput:self.input];

        NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:@"anObject"];
        PHAdjustmentData *adjustmentData = [[PHAdjustmentData alloc] initWithFormatIdentifier:@"org.someapp.FilterShowContainer.iFilters"
                                                                                formatVersion:@"1.0"
                                                                                         data:archivedData];
        contentEditingOutput.adjustmentData = adjustmentData;

        // Get full size image
        NSURL *url = self.input.fullSizeImageURL;

        // Generate rendered JPEG data
        UIImage *image = [UIImage imageWithContentsOfFile:url.path];

        image = [filter imageByFilteringImage:self.input.displaySizeImage]; //this one works as expected. However, the resulting image is in lowres (screen size)
        image = [filter imageByFilteringImage:image]; //this one even if the image is correctly generated does not produce any change on the original photo

        NSData *renderedJPEGData = UIImageJPEGRepresentation(image, 0.3f);

        // Save JPEG data
        NSError *error = nil;
        BOOL success = [renderedJPEGData writeToURL:contentEditingOutput.renderedContentURL options:NSDataWritingAtomic error:&error];
        if (success) {
            completionHandler(contentEditingOutput);
        } else {
            NSLog(@"An error occured: %@", error);
            completionHandler(nil);
        }
    });
}

When dialing with display size it works as expected and the original image is changed according. However, as explained in code comment, if I use the original size image, it produce the output but the Library image is not changed.

Is this a known issue? Any clues?

Thanks

twentyfourapp commented 10 years ago

Having the same issue. Were you able to get it to work? I would hate to drop GPUImage from my app. By far my favorite library.

twentyfourapp commented 10 years ago

One thing I noticed is that it works correctly on images downloaded/saved from any other source but images taken with the camera just crashes/freezes the extension.

valvoline commented 10 years ago

Perhaps the problem is not related with the image source. Instead it seems to be a memory issue closely related to image size.

twentyfourapp commented 10 years ago

That is what I'm thinking as well, unfortunately I think you need to save that large image back to the photo library so the main editor can show it in its edited state. Did you ever get anything working?

BradLarson commented 10 years ago

What are the crashes you're getting? What's the stack trace? What's logged to the console? I honestly haven't even installed iOS 8 on any of my devices. Haven't had the time.

I can't even start to debug something without a stack trace or other crash information.

twentyfourapp commented 10 years ago

Unfortunately I can't seem to get any stack traces/log outputs on xcode for app extensions. It seems to be memory constraints error in processing my filter chains. I will probably have to look into doing some better memory management but there really isn't much more I can take out. Some other users might run into this issue with the photo filter extensions unfortunately.

twentyfourapp commented 10 years ago

After doing some more profiling etc it seems memory spikes to 80mb sometimes which is of course ok in a regular app but seems to be too much for an app extension. Smaller photos will work (screen shots etc) but filtering the larger images ones with true high res backed images (shots taken by the camera) seem to be the main issues. Any advice on keeping memory low in creating a custom filter? My filters use ACV files along with filter targets added on after. Thank you.

twentyfourapp commented 10 years ago

As a side note when it randomly does not crash I get errors in my console stating....

-assetsd Error: Invalid image orientation ios

I filter an image starting with an ACV file then add sharpen/tone/etc. From then I call imageFromCurrentFramebufferWithOrientation:orientation to get my filtered image. The issue is I have to convert from EXIF number UIImageOrientation value. I do this like below

-(UIImageOrientation)imageOrientationFromOrientation:(int)orientation { UIImageOrientation imageOrientation = UIImageOrientationUp;

switch (orientation)
{
    case 1:     imageOrientation = UIImageOrientationUp; break;
    case 3:     imageOrientation = UIImageOrientationDown; break;
    case 8:     imageOrientation = UIImageOrientationLeft; break;
    case 6:     imageOrientation = UIImageOrientationRight; break;
    case 2:     imageOrientation = UIImageOrientationUpMirrored; break;
    case 4:     imageOrientation = UIImageOrientationDownMirrored; break;
    case 5:     imageOrientation = UIImageOrientationLeftMirrored; break;
    case 7:     imageOrientation = UIImageOrientationRightMirrored; break;
    default:    imageOrientation = UIImageOrientationUp; break;
}
return imageOrientation;

}

Unfortunately majority of the time I get the above error I mentioned in my console. Am I feeding your imageFromCurrentFramebufferWithOrientation:orientation method the right data? Many of the times the EXIF data is 6 for orientation, which seems odd to me since I am taking the photo in portrait mode home bottom on the bottom. Any advice would be greatly appreciated. Thanks again.

parthpatel1105 commented 9 years ago

switch(_outputImageOrientation) { case UIInterfaceOrientationPortrait:outputRotation = kGPUImageRotateRightFlipVertical; break; case UIInterfaceOrientationPortraitUpsideDown:outputRotation = kGPUImageRotate180; break; case UIInterfaceOrientationLandscapeLeft:outputRotation = kGPUImageFlipHorizonal; break; case UIInterfaceOrientationLandscapeRight:outputRotation = kGPUImageFlipVertical; break; }

I got error in _outputImageOrientation. is there any solution?

Error is: Enumeration value 'UIInterfaceOrientationUnknown' not handle in switch.

tombeta commented 7 years ago

Hey, did u find a solution for your problem? I'm faced with a very similiar problem...

ewindso commented 7 years ago

This may help: https://stackoverflow.com/questions/45490411/phassetchangerequest-fails-unless-original-image-orientation-is-landscape-left/45492979#45492979