带边框的UIImage。无效的上下文0x0

时间:2012-08-27 16:37:13

标签: iphone ios uiimage core-graphics cgcontext

我正在获取图像并将其保存到后台线程中的临时目录中。在保存之前,我想为这个UIImage添加一个小的白色边框。我这样做:

    - (UIImage *)imageWithBorder:(UIImage *)image {
    CGSize newSize = CGSizeMake(image.size.width, image.size.height);
    CGRect rect = CGRectMake(0.0, 0.0, image.size.width, image.size.height);

    UIGraphicsBeginImageContextWithOptions(newSize, NO, image.scale); {
        CGContextRef context = UIGraphicsGetCurrentContext();

        CGContextBeginTransparencyLayer (context, NULL);
        //Draw
        [image drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0];
        CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
        CGContextStrokeRectWithWidth(context, rect, 10);
        CGContextEndTransparencyLayer(context);
    }
    UIImage *result =  UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return result;
}

一切都没问题,从临时目录加载该图像后,我可以在图像上看到边框,但在控制台中,当下面的代码实现时,我得到invalid context 0x0。这有什么不对?


更新01

- (UIImage *)imageWithBorder:(UIImage *)image {
    CGSize newSize = CGSizeMake(image.size.width, image.size.height);
    CGRect rect = CGRectMake(0.0, 0.0, image.size.width, image.size.height);

    UIGraphicsBeginImageContextWithOptions(newSize, NO, image.scale); {
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextDrawImage (context, rect, [image CGImage]);
        CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
        CGContextStrokeRectWithWidth(context, rect, 10);
    }
    UIImage *result =  UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return result;
}

2 个答案:

答案 0 :(得分:1)

  

UIGraphicsGetCurrentContext返回当前图形上下文。

     

CGContextRef UIGraphicsGetCurrentContext(void);返回值   当前的图形上下文。

     

讨论默认情况下,当前图形上下文为零。之前   调用其drawRect:方法,视图对象将有效的上下文推送到   堆栈,使其成为最新的。如果您没有使用UIView对象   但是,您必须将有效的上下文推送到堆栈中   手动使用UIGraphicsPushContext函数。

     

您应该从应用程序的主线程中调用此函数   仅

这是UIKit Function Reference

答案 1 :(得分:1)

尝试更改:

[image drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0];

CGContextDrawImage (context, rect, [image CGImage]);

另外,为什么要使用透明层?你将alpha设置为1,所以你可以覆盖原始图像,不是吗?

编辑:我刚刚在我的应用程序中运行了相同的代码,在后台运行,它完美无缺:

- (UIImage *)imageWithBorder:(UIImage *)image
{
    NSLog(@"Thread %@", [NSThread currentThread]);

    CGSize newSize = CGSizeMake(image.size.width, image.size.height);
    CGRect rect = CGRectMake(0.0, 0.0, image.size.width, image.size.height);

    UIGraphicsBeginImageContextWithOptions(newSize, NO, image.scale);
    CGContextRef context = UIGraphicsGetCurrentContext();

    //Draw
    CGContextDrawImage(context, rect, [image CGImage]);
    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
    CGContextStrokeRectWithWidth(context, rect, 10);
    UIImage *result =  UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();
assert(result);
    return result;
}

当我在viewDidAppear中执行此操作时:(但它的图像很小,可能尺寸相关吗?)

dispatch_async(dispatch_get_global_queue(0, 0), ^{ [self imageWithBorder:[UIImage imageNamed:@"02-redo.png"]] ; } );

这就是我在日志中看到的全部内容:

2012-08-27 13:48:04.679 Searcher[32825:11103] Thread <NSThread: 0x6d30e30>{name = (null), num = 4}

所以你的代码还有其他的东西。我正在使用Xcode 4.4.1构建,部署目标是5.1

编辑:在您的区块中,您不能引用“单元格”,因为单元格是暂时的 - 通过回收它可能甚至不可见。因此,图像名称将通过本地NSString进行路由,然后最后,您需要另一种可以将图像发布到的方法以及单元格indexPath。该方法将查看indexPath是否在表的visibleCells中,如果是,则更新图像,如果不是,则要存储图像,以便可以与tableView一起使用,然后请求该单元格。

EDIT2:此代码:

dispatch_async(queue, ^{ 
  UIImage *image = [_thumbnailMaster thumbnailForItemWithFilename:cell.label.text];
  dispatch_sync(dispatch_get_main_queue(), ^{ cell.thumbnailView.image = image; }); 
});

应该变成不涉及“细胞”的东西,因为细胞可能超出范围或被另一个指数使用(假设回收)。像这样:

NSString *text = cell.label.text;
NSIndexPath *path = ...;

dispatch_async(queue, ^{ 
  UIImage *image = [_thumbnailMaster thumbnailForItemWithFilename:text];  
   dispatch_sync(dispatch_get_main_queue(), ^{ [self updateCellImage:image withPath"path]; }); 
});

您的方法确定该单元格是否可见,如果是,则更新图像,如果不保存,则下次需要时可以使用它。