我正在创建一个简单的绘图应用程序,并希望根据用户的触摸事件绘制矩形。我可以使用Core Graphics从touchesBegan到touchesEnded中的点绘制一个矩形。触发touchesEnded事件后,将显示此矩形。
但是,我希望能够以“现场”的方式做到这一点。意思是,当用户拖动手指时,矩形会更新并显示。这可能吗?非常感谢任何帮助,谢谢!
更新
我可以使用以下代码使其工作。它适用于小图像,但对于大图像来说速度非常慢。我意识到我的解决方案非常低效,并且想知道是否有人可以提出更好的解决方案。感谢。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
_firstPoint = [touch locationInView:self.view];
_firstPoint.y -= 40;
_lastPoint = _firstPoint;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
currentPoint.y -= 40;
[self drawSquareFrom:_firstPoint to:currentPoint];
_lastPoint = currentPoint;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
currentPoint.y -= 40;
[self drawSquareFrom:_firstPoint to:currentPoint];
[_modifiedImage release];
_modifiedImage = [[UIImage alloc] initWithCGImage:_imageView.image.CGImage];
}
- (void)drawSquareFrom:(CGPoint)firstPoint to:(CGPoint)lastPoint
{
_imageView.image = _modifiedImage;
CGFloat width = lastPoint.x - firstPoint.x;
CGFloat height = lastPoint.y - firstPoint.y;
_path = [UIBezierPath bezierPathWithRect:CGRectMake(firstPoint.x, firstPoint.y, width, height)];
UIGraphicsBeginImageContext( _originalImage.size );
[_imageView.image drawInRect:CGRectMake(0, 0, _originalImage.size.width, _originalImage.size.height)];
_path.lineWidth = 10;
[[UIColor redColor] setStroke];
[[UIColor clearColor] setFill];
[_path fill];
[_path stroke];
_imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
答案 0 :(得分:0)
您现在正在做的是为CGImage
的每次调用创建配对的CGBitmapContext
和drawSquareFrom:to:
并每次处理它们。而是创建一个您为每次调用重复使用的单个配对CGImage
和CGBitmapContext
。
-(void) drawSquareFrom:(CGPoint)from to:(CGPoint)to {
CGContextRef context = [self offscreenContext];
CGRect draw , full = [self offscreenContextBounds];
draw.origin = from;
draw.size.width = to.x - from.x;
draw.size.height = to.y - from.y;
draw = CGRectStandardize( draw );
[[UIColor redColor] setStroke];
[[UIColor clearColor] setFill];
CGContextClearRect( context , full );
CGContextFillRect( context , draw );
CGContextStrokeRectWithWidth( context , draw , 10 );
[_imageView setNeedsDisplay];
}
你创建一个像这样的配对CGImage和CGContext,虽然有一些......要填写。所有的myX变量都是类成员。
-(CGContextRef) offscreenContext {
if ( nil == myContext ) {
size_t width = 400;
size_t height = 300;
CFMutableDataRef data = CFDataCreateMutable( NULL , width * height * 4 ); // 4 is bytes per pixel
CGDataProviderRef provider = CGDataProviderCreateWithCFData( data );
CGImageRef image = CGImageCreate( width , height , ... , provider , ... );
CGBitmapContextRef context = CGBitmapContextCreate( CFDataGetMutableBytePtr( data ) , width , height , ... );
CFRelease( data ); // retained by provider I think
CGDataProviderRelease( provider ); // retained by image
myImage = image;
myContext = context;
myContextFrame.origin = CGPointZero;
myContextFrame.size.width = width;
myContextFrame.size.height = height;
_imageView.image = [UIImage imageWithCGImage:image];
}
return myContext;
}
-(CGRect) offscreenContextBounds {
return myContextFrame;
}
这会将_imageView.image设置为新创建的图像。在drawSquareFrom:to:
中,我假设setNeedsDisplay足以绘制所做的更改,但是每次包装相同的CGImage时,您可能需要分配一个新的UIImage。
答案 1 :(得分:0)
只需使用两个上下文。 在一个你只需“预览”绘制矩形,你可以在TouchesMoved上清除它。 在TouchesEnd上,您最终将绘制原始上下文,然后绘制在图像上。