我正在获取图像并将其保存到后台线程中的临时目录中。在保存之前,我想为这个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;
}
答案 0 :(得分:1)
UIGraphicsGetCurrentContext返回当前图形上下文。
CGContextRef UIGraphicsGetCurrentContext(void);返回值 当前的图形上下文。
讨论默认情况下,当前图形上下文为零。之前 调用其drawRect:方法,视图对象将有效的上下文推送到 堆栈,使其成为最新的。如果您没有使用UIView对象 但是,您必须将有效的上下文推送到堆栈中 手动使用UIGraphicsPushContext函数。
您应该从应用程序的主线程中调用此函数 仅
答案 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]; });
});
您的方法确定该单元格是否可见,如果是,则更新图像,如果不保存,则下次需要时可以使用它。