jameswomack / iOS-Image-Filters

High-level CIImage-based image filtering on iOS 6+ using CoreImage & raster graphic overlays
http://womack.io
MIT License
132 stars 27 forks source link

When used on large images, the result is cropped to a small portion of the image #9

Open peterpaulis opened 8 years ago

peterpaulis commented 8 years ago

No sure where the problem is, but when a large image is used 3000x2000 than the result is just a cropped portion of the original

In my implementation it was happening too, so i wanted to give yours a try, but the the same problem there

peterpaulis commented 8 years ago

this is only the case when using blur

jameswomack commented 8 years ago

I'll look into this @peterpaulis, thank you for reporting the issue. Please report back if you find a solution to :smile:

peterpaulis commented 8 years ago

the problem is also with CIBloom as well

peterpaulis commented 8 years ago

found the problem, looks like some images report incorrect size and than the crop gets wrong

using the alternative to find the size bellow (and than cropping with it!) fixed the issue, but more research on this would be welcome

- (NGImage *)filter:(NSString *)filterName params:(NSDictionary *)theParams {
  NGImage *uiImage;

    NSLog(@"%f %f", self.image.size.width, self.image.size.height);

    NSSize imageSize = self.image.size;
    {
        NSInteger width = 0;
        NSInteger height = 0;

        for (NSImageRep * imageRep in self.image.representations) {
            if ([imageRep pixelsWide] > width) width = [imageRep pixelsWide];
            if ([imageRep pixelsHigh] > height) height = [imageRep pixelsHigh];
        }

        imageSize.width = width;
        imageSize.height = height;

        NSLog(@"Width from NSBitmapImageRep: %f",(CGFloat)width);
        NSLog(@"Height from NSBitmapImageRep: %f",(CGFloat)height);
    }

  CIImage *image = self.image.ng_CIImage;

  BOOL shouldClamp = theParams.allKeys.count && theParams[@"inputRadius"];
  if (shouldClamp) {
    image = [image ng_imageByClampingToExtent];
  }

  CIFilter *filter = [CIFilter withName:filterName andCIImage:image];

  [theParams enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop __unused) {
    [filter setValue:obj forKey:key];
  }];

  CIImage* outputImage = filter.outputImage;

  CGRect extent = shouldClamp ? (CGRect){.size = imageSize} : outputImage.extent;
  self.image = uiImage = [outputImage UIImageFromExtent:extent];

    return uiImage;
}
peterpaulis commented 8 years ago

a good approach looks like getting the size from CIImage, but with concating multiple filters, this could be a problem as sometime the extent is infinite

- (NGImage *)filter:(NSString *)filterName params:(NSDictionary *)theParams {
  NGImage *uiImage;

    CIImage *image = self.image.ng_CIImage;
    NSSize imageSize = [image extent].size;