【问题标题】:iPhone Difference Handling Images Between Device and SimulatoriPhone在设备和模拟器之间处理图像的差异
【发布时间】:2012-11-08 13:37:02
【问题描述】:

我有一个带有透明边框的图像,我正在尝试按照here 找到的 Apple 指南直接操作图像像素。在设备上运行时一切正常。但是,当我在模拟器上运行我的代码时,我发现每次调用此函数时,图像的透明边框都会慢慢变黑。奇怪的是,即使我不修改图像数据,每次调用这个函数时,透明边框仍然开始变黑。例如,即使我的图像处理代码调用CGBitmapContextGetData 但不使用返回的数据指针,我也会看到同样的问题。为了使模拟器上的问题消失,我必须注释掉对CGBitmapContextGetData 的调用(当然还要释放数据指针)。仍然在模拟器上修改图像的示例代码:

+ (UIImage *) updateImage:(UIImage *)inputImage
{
    UIImage *updatedImage;

    /* Update colors in image appropriately */
    CGImageRef image = [inputImage CGImage];

    CGContextRef cgctx = [ColorHandler CreateARGBBitmapContext:image];
    if (cgctx == NULL)
    {
        // error creating context
        NSLog(@"Error creating context.\n");
        return nil;
    }

    size_t w = CGImageGetWidth(image);
    size_t h = CGImageGetHeight(image);
    CGRect rect = {{0,0},{w,h}};

    // Draw the image to the bitmap context. Once we draw, the memory
    // allocated for the context for rendering will then contain the
    // raw image data in the specified color space.
    CGContextDrawImage(cgctx, rect, image);

    // Now we can get a pointer to the image data associated with the bitmap
    // context.
    void *data = CGBitmapContextGetData(cgctx);

    CGImageRef ref = CGBitmapContextCreateImage(cgctx);
    updatedImage = [UIImage imageWithCGImage:ref];
    // When finished, release the context
    CGContextRelease(cgctx);
    CGImageRelease(ref);

    // Free image data memory for the context
    if (data)
    {
        free(data);
    }

    return updatedImage;    
}

我阅读了the comments and answers here,了解如何在设备和模拟器之间以不同方式管理图像,但它并没有帮助我找出我的问题。

我的CreateARGBBitmapContext 和示例之间的唯一区别是我调用CGColorSpaceCreateDeviceRGB 而不是CGColorSpaceCreateWithName,因为我的目标是iOS。图像在 iOS 设备上运行时完全按照设计进行编辑。

我目前正在主线程中进行所有图像处理以调试此问题。

规格:Mountain Lion,XCode 4.5.2,iOS 6 设备,iOS 6 模拟器

【问题讨论】:

    标签: iphone ios uiimage ios-simulator cgcontext


    【解决方案1】:

    我能够通过允许 Quartz 分配和管理位图 (Apple doc) 的内存来解决这个问题。为此,我在CreateARGBBitmapContext 中更新了对CGBitmapContextCreate 的调用以传递NULL,并删除了对bitmapData 的所有引用。

    // Create the bitmap context. We want pre-multiplied ARGB, 8-bits 
    // per component. Regardless of what the source image format is 
    // (CMYK, Grayscale, and so on) it will be converted over to the format
    // specified here by CGBitmapContextCreate.
    context = CGBitmapContextCreate (NULL,
                                    pixelsWide,
                                    pixelsHigh,
                                    8,      // bits per component
                                    bitmapBytesPerRow,
                                    colorSpace,
                                    kCGImageAlphaPremultipliedFirst);
    

    然后,在updateImage 方法中,我删除了data 的释放。现在它似乎在设备和模拟器上都可以正常工作。

    【讨论】:

    • 也许您没有将传递给 CGBitmapContextCreate() 的内存归零?
    • @tc。我没有将传递给 CGBitmapContextCreate 的内存归零。苹果的例子也没有将内存归零。我还没有机会测试这是否也能解决问题,但是是什么让你认为它会解决?我假设 CGContextDrawImage 无论如何都会覆盖所有数据。
    • 如果你的图片是透明的,那么CGContextDrawImage会默认做一个alpha混合;您可以使用kCGBlendModeCopy 直接复制(也许这就是您想要的效率)。如果您不需要支持 iOS 4 以下,我还建议使用UIGraphicsBeginImageContextWithOptions()
    • @tc。我明白你的意思了。我会试试你的建议,然后告诉你结果。
    • @tc。我添加了对CGContextSetBlendMode 的调用,按照您的建议设置kCGBlendModeCopy。但是,如果我想访问像素数据,我不明白如何使用UIGraphicsBeginImageContextWithOptions?我不必使用位图上下文来直接访问像素数据吗?我没有检查UIImagePNGRepresentation 返回的数据,但我不认为编辑该数据实际上会编辑图像。无论如何,感谢您的kCGBlendModeCopy 建议。
    猜你喜欢
    • 2011-03-04
    • 1970-01-01
    • 2013-09-09
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    相关资源
    最近更新 更多