我有一个支持 CATiledLayer 的 UIScrollView,它显示了一个非常大的图像。 我想要实现的是将此 View 捕获到 UIImage 中(将其用作进度条 View 的背景)。 有几个问题:
- 在“100%”缩放(整个图片可见)看起来还可以
- 如果我放大 ScrollView ,一些图 block 会变形(比例和/或偏移量不好)
- 尝试使用 Apple 的 PhotoScroller 示例重现它,几乎可以正常工作,只是捕获的图像有时会像素化
- 我没有写代码,所以我不知道如何修复它
检查了与此相关的其他 stackoverflow 条目,但它们并没有多大帮助......
图片获取代码:
CGRect rect = [view bounds];
UIImage* img = nil;
if ([view isKindOfClass:[UIScrollView class]])
{
UIScrollView* scrollview = (UIScrollView*)view;
CGPoint contentOffset = scrollview.contentOffset;
UIGraphicsBeginImageContextWithOptions(rect.size, view.opaque, 0.0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -contentOffset.x, -contentOffset.y);
[view.layer renderInContext:ctx];
img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
以及平铺 View 的 drawRect: 方法的代码:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
if (self.clipContent)
{
CGContextSaveGState(context);
CGFloat color[4] = {1.0, 1.0f, 1.0f, 1.0f};
CGContextSetFillColor(context, color);
CGContextFillRect(context, self.bounds);
CGRect clips[] = {
CGRectMake(self.bounds.size.width / 2.0, 0,
self.bounds.size.height / 2.0 , self.bounds.size.width / 2.0)
};
CGContextClipToRects(context, clips, sizeof(clips) / sizeof(clips[0]));
}
CGFloat scale = CGContextGetCTM(context).a;
CGSize tileSize = [_dataSource tileSize];
double width = (double)tileSize.width / (double)scale;//pow(2.0, (int)log2(scale));
double height = (double)tileSize.height / (double)scale;//pow(2.0, (int)log2(scale));
int firstCol = floorf(CGRectGetMinX(rect) / width);
int lastCol = floorf((CGRectGetMaxX(rect) - 1) / width);
int firstRow = floorf(CGRectGetMinY(rect) / height);
int lastRow = floorf((CGRectGetMaxY(rect) - 1) / height);
for (int row = firstRow; row <= lastRow; row++) {
for (int col = firstCol; col <= lastCol; col++) {
UIImage* tileImage = [_dataSource tileForScale:scale row:row col:col];
CGRect tileRect = CGRectMake(width * col, height * row, width, height);
tileRect = CGRectIntersection(rect, tileRect);
[tileImage drawInRect:tileRect];
}
}
if (self.clipContent)
CGContextRestoreGState(context);
}
有什么想法吗?
最佳答案
经过反复试验,发现是Cocoa实现本身不完善,无法解决问题。
随着 iOS 7 的发布,有一种新的方法:
[view drawViewHierarchyInRect:rect afterScreenUpdates:YES];
(而不是 renderInContext),并且它有效(图像有点模糊,但这是可以接受的副作用)。
关于iOS - CATiledLayer renderInContext : results in distorted image,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17612350/