gpt4 book ai didi

iphone - 带有 CGBitmapContext 的 Drawrect 太慢了

转载 作者:可可西里 更新时间:2023-11-01 05:02:57 24 4
gpt4 key购买 nike

所以我在这个过程中有一个基本的绘图应用程序,可以让我画线。我绘制到屏幕外位图,然后在 drawRect 中显示图像。它可以工作,但速度太慢,在您用手指绘制后约半秒更新一次。我从本教程中获取代码并对其进行了改编,http://www.youtube.com/watch?v=UfWeMIL-Nu8&feature=relmfu ,正如您在评论中看到的那样,人们也说它太慢了,但那个人没有回应。

那么我怎样才能加快速度呢?或者有更好的方法吗?任何指针将不胜感激。

这是我的 DrawView.m 中的代码。

-(id)initWithCoder:(NSCoder *)aDecoder {
if ((self=[super initWithCoder:aDecoder])) {
[self setUpBuffer];
}

return self;
}

-(void)setUpBuffer {
CGContextRelease(offscreenBuffer);

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

offscreenBuffer = CGBitmapContextCreate(NULL, self.bounds.size.width, self.bounds.size.height, 8, self.bounds.size.width*4, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);

CGContextTranslateCTM(offscreenBuffer, 0, self.bounds.size.height);
CGContextScaleCTM(offscreenBuffer, 1.0, -1.0);
}


-(void)drawToBuffer:(CGPoint)coordA :(CGPoint)coordB :(UIColor *)penColor :(int)thickness {

CGContextBeginPath(offscreenBuffer);
CGContextMoveToPoint(offscreenBuffer, coordA.x,coordA.y);
CGContextAddLineToPoint(offscreenBuffer, coordB.x,coordB.y);
CGContextSetLineWidth(offscreenBuffer, thickness);
CGContextSetLineCap(offscreenBuffer, kCGLineCapRound);
CGContextSetStrokeColorWithColor(offscreenBuffer, [penColor CGColor]);
CGContextStrokePath(offscreenBuffer);

}

- (void)drawRect:(CGRect)rect {
CGImageRef cgImage = CGBitmapContextCreateImage(offscreenBuffer);
UIImage *image =[[UIImage alloc] initWithCGImage:cgImage];
CGImageRelease(cgImage);
[image drawInRect:self.bounds];

}

在模拟器上完美运行,但在设备上运行不佳,我想这与处理器速度有关。

我正在使用 ARC。

最佳答案

我试图修复您的代码,但是由于您似乎只发布了一半,我无法让它工作(复制+粘贴代码会导致很多错误,更不用说开始性能调整了)。

但是,您可以使用一些技巧来显着提高性能。

第一个可能是最引人注目的是 -setNeedsDisplayInRect: 而不是 -setNeedsDisplay。这意味着它只会重绘发生变化的小矩形。对于 1024*768*4 像素的 iPad 3,工作量很大。将每帧减少到大约 20*20 或更少将大大提高性能。

CGRect rect;
rect.origin.x = minimum(coordA.x, coordB.x) - (thickness * 0.5);
rect.size.width = (maximum(coordA.x, coordB.x) + (thickness * 0.5)) - rect.origin.x;
rect.origin.y = minimum(coordA.y, coordB.y) - (thickness * 0.5);
rect.size.height = (maximum(coordA.y, coordB.y) + (thickness * 0.5)) - rect.origin.y;
[self setNeedsDisplayInRect:rect];

您可以做出的另一项重大改进是仅为当前触摸(您所做的)绘制 CGPath。但是,您随后在绘制矩形中绘制保存/缓存的图像。因此,它再次在每一帧重新绘制。更好的方法是让绘图 View 透明,然后在其后面使用 UIImageView。 UIImageView 是在 iOS 上显示图像的最佳方式。

- DrawView (1 finger)
-drawRect:
- BackgroundView (the image of the old touches)
-self.image

绘制 View 本身将只绘制当前触摸每次变化的部分。当用户抬起手指时,您可以将其缓存到 UIImage,在当前背景/缓存 UIImageView 的图像上绘制它,并将 imageView.image 设置为新图像。

组合图像的最后一点涉及将 2 个全屏图像绘制到屏幕外的 CGContext 中,因此如果在主线程上完成会导致延迟,而这应该在后台线程中完成,然后将结果推送回主线程。

* touch starts *
- DrawView : draw current touch
* touch ends *
- 'background thread' : combine backgroundView.image and DrawView.drawRect
* thread finished *
send resulting UIImage to main queue and set backgroundView.image to it;
Clear DrawView's current path that is now in the cache;

所有这些结合在一起可以制作出非常流畅的 60fps 绘图应用程序。然而, View 并没有像我们希望的那样快速更新,因此在更快地移动图形时绘图看起来呈锯齿状。这可以通过使用 UIBezierPath 而不是 CGPaths 来改进。

CGPoint lastPoint = [touch previousLocationInView:self];
CGPoint mid = midPoint(currentPoint, lastPoint);
-[UIBezierPath addQuadCurveToPoint:mid controlPoint:lastPoint];

关于iphone - 带有 CGBitmapContext 的 Drawrect 太慢了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11261450/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com