CoreGraphics 在大 UIImage 上绘图
Posted
技术标签:
【中文标题】CoreGraphics 在大 UIImage 上绘图【英文标题】:CoreGraphics drawing on a large UIImage 【发布时间】:2011-08-08 23:21:34 【问题描述】:我有一个 UIImage,我在它上面画出跟随用户手指的线条。这就像一个绘图板。这在 UIImage 很小(比如 500 x 600)时非常有效,但如果它像 1600 x 1200 一样,它会变得非常粗糙和滞后。有没有办法可以优化这个?这是我在 touchesModed 中的绘图代码:
UIGraphicsBeginImageContext(self.frame.size);
[drawImageView.image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 15.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
//CGContextSetAlpha(UIGraphicsGetCurrentContext(), 0.5f);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
谢谢。
【问题讨论】:
【参考方案1】:与其一次性绘制整个 1600X1200 帧,不如根据需要绘制它。我的意思是,由于您正在绘制整个帧(驻留在内存中),因此您的性能参差不齐。
试试CATiledLayer。基本上,您只需要绘制您的设备能够绘制的屏幕尺寸,除此之外,当用户滚动时,您需要动态绘制它。
这是在 iPad 或 iPhone 上的 Google 地图中使用的。希望这会有所帮助...
【讨论】:
【参考方案2】:不是每次触摸移动时都创建一个新上下文并将当前图像绘制到其中,而是使用CGBitmapContextCreate
创建一个上下文并重用该上下文。之前的所有绘图都已经在上下文中,并且您不必在每次触摸移动时都创建新的上下文。
- (CGContextRef)drawingContext
if(!context) // context is an instance variable of type CGContextRef
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if(!colorSpace) return nil;
context = CGBitmapContextCreate(NULL, contextSize.width, contextSize.height,
8, contextSize.width * 32, colorSpace,
kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(colorSpace);
if(!context) return nil;
CGContextConcatCTM(context, CGAffineTransformMake(1,0,0,-1,0,contextSize.height));
CGContextDrawImage(context, (CGRect)CGPointZero,contextSize, drawImageView.image.CGImage);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 15.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
return context;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
CGContextRef ctxt = [self drawingContext];
CGContextBeginPath(ctxt);
CGContextMoveToPoint(ctxt, lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(ctxt, currentPoint.x, currentPoint.y);
CGContextStrokePath(ctxt);
CGImageRef img = CGBitmapContextCreateImage(ctxt);
drawImageView.image = [UIImage imageWithCGImage:img];
CGImageRelease(img);
此代码需要实例变量CGContextRef context
和CGSize contextSize
。上下文需要在 dealloc 中释放,并且每当您更改其大小时。
【讨论】:
以上是关于CoreGraphics 在大 UIImage 上绘图的主要内容,如果未能解决你的问题,请参考以下文章