代码之家  ›  专栏  ›  技术社区  ›  bmauter

无法在iOS7上使用GPUImage缩放UIImage

  •  0
  • bmauter  · 技术社区  · 10 年前

    我有一年多的代码成功地缩放、旋转并将UIImage转换为1bpp(黑白)。它在我的iPhone 5s、我测试过的iPad等上运行良好。然而,运行iOS 7.1.2的iPhone 4崩溃了。

    我的代码(UIImage上的一个类别)是:

    - (void) prepareImageForOCRWithCompletionHandler:(void (^) (UIImage *image))completion {
    
        if (!completion) return; // no sense in doing anything if nobody listens for the completion
    
        int width = self.size.width;
        int height = self.size.height;
    
        DLog(@"width=%d, height=%d", width, height);
    
        if (width > height) {
            int temp = width;
            width = height;
            height = temp;
        }
    
        int scaledWidth = 1728; // class F tiffs should be 1728, 2048 or 2483 pixels wide http://www.libtiff.org/support.html
        int scaledHeight = scaledWidth * height / width;
    
        DLog(@"width=%d, height=%d, scaledWidth=%d, scaledHeight=%d", width, height, scaledWidth, scaledHeight);
    
        GPUImagePicture *source = [[GPUImagePicture alloc] initWithImage:self];
    
        GPUImageFilter *rotateFilter = [[GPUImageFilter alloc] init];
        [rotateFilter setInputRotation:kGPUImageRotateRight atIndex:0];
    
        GPUImageTransformFilter *scaleFilter = [[GPUImageTransformFilter alloc] init];
        [scaleFilter forceProcessingAtSizeRespectingAspectRatio:CGSizeMake(scaledWidth, scaledHeight)];
    
        GPUImageAdaptiveThresholdFilter *thresholdFilter = [[GPUImageAdaptiveThresholdFilter alloc] init];
    
        [source addTarget:rotateFilter];
        [rotateFilter addTarget:scaleFilter];
        [scaleFilter addTarget:thresholdFilter];
    
        [source processImageWithCompletionHandler:^{
            UIImage *result = [thresholdFilter imageFromCurrentlyProcessedOutput];
            completion(result);
        }];
    }
    

    在Xcode控制台中使用以下消息调用GPUImage完成处理程序之前,应用程序崩溃:

    2015-02-05 13:39:10.131 MyApp[345:60b] -[UIImage(BJM) prepareImageForOCRWithCompletionHandler:] [Line 54] width=1936, height=2592
    2015-02-05 13:39:10.133 MyApp[345:60b] -[UIImage(BJM) prepareImageForOCRWithCompletionHandler:] [Line 65] width=1936, height=2592, scaledWidth=1728, scaledHeight=2313
    2015-02-05 13:39:12.328 MyApp[345:7273] *** Assertion failure in -[GPUImageTransformFilter createFilterFBOofSize:], /Users/brian/repos/GPUImage/framework/Source/GPUImageFilter.m:380
    2015-02-05 13:39:12.364 MyApp[345:7273] void uncaughtExceptionHandler(NSException *__strong) [Line 75] uncaught exception: Incomplete filter FBO: 36054
    2015-02-05 13:39:12.366 MyApp[345:7273] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Incomplete filter FBO: 36054'
    *** First throw call stack:
    (0x30560f83 0x3ad11ccf 0x30560e5d 0x30f0ed5b 0x2a7adf 0x2aa82d 0x2a73a7 0x2a7c77 0x2a7daf 0x2b0265 0x2a80d5 0x2a9285 0x2acd49 0x3b1f9833 0x3b1f9ded 0x3b1fa297 0x3b20c88d 0x3b20cb21 0x3b33bbd3 0x3b33ba98)
    libc++abi.dylib: terminating with uncaught exception of type NSException
    

    如果我从管道中删除GPUImageTransformFilter,它就会工作。如果我恢复了变换过滤器,但将1728更改为1000,它也会起作用。这似乎是原始图像太小的问题。然而,原件是1936x2592。我还将宽度和高度int改为CGFloats,认为舍入错误导致了问题。没有运气。

    这确实是一个令人羞愧的问题。谢谢你抽出时间。

    1 回复  |  直到 10 年前
        1
  •  2
  •   Brad Larson    10 年前

    您的问题与图像大小有关。在错误读数中,我看到您在图像中使用了2592的高度。

    对于iPhone 4和更旧的设备,其GPU在两个维度上的纹理大小限制为2048。尝试创建大于宽度或高度的纹理将导致失败,这是我的断言。

    不幸的是,我目前不支持大于任何GPU纹理限制的图像。您需要找到另一种方法来调整这些旧设备上大于2048x2048的图像的大小。我在框架内的一些地方(例如,处理在iPhone4上拍摄的照片)做了这项工作,但不是在任何地方。