2010-07-03 4 views
2

사용자가 iPad/iPhone 화면에서 손가락을 움직일 때 점선이 그려지는보기가 있습니다. LastLocation으로 저장된 점과 CurrentLocation 인 점 사이에 선을 그립니다. 도면은 화면 상에 지속되어야한다. 이 문제는 touchMoved 이벤트가 발생할 때마다 발생하며 그림 응용 프로그램과 마찬가지로 손가락을 드래그 한 위치에서 점선을 그릴 수있게됩니다.더 나은 성능을 가진 UIImageView에서 페인팅

나는 touch 이벤트가 발생하면 다음과 같은 함수를 호출한다. 뷰에는 drawImage라는 UIImageView가 포함되어 있습니다. UIImageView를 그려진 선을 지속하는 수단으로 사용합니다. 이것은 사람들이 일반적으로 응용 프로그램을 그리는 방법과는 달리 매우 느립니다. CGContextRef 호출을 사용하여 지속적인 그림을 만드는 더 좋은 방법에 대한 통찰력은 인정 될 것입니다.

/* Enter bitmap graphics drawing context */ 
UIGraphicsBeginImageContext(frame.size); 
/* Draw the previous frame back in to the bitmap graphics context */ 
[drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)]; //originally self.frame.size.width, self.frame.size.height)];  
/* Draw the new line */ 
CGContextRef ctx = UIGraphicsGetCurrentContext(); 
/* Set line draw color to green, rounded cap end and width of 5 */ 
CGContextSetLineDash(ctx, 0, dashPattern, 2); 
CGContextSetStrokeColorWithColor(ctx, color); 
CGContextSetLineCap(ctx, kCGLineCapRound); //kCGLineCapSquare, kCGLineCapButt, kCGLineCapRound 
CGContextSetLineWidth(ctx, 5.0); // for size 
/* Start the new path point */ 
CGContextMoveToPoint(ctx, LastLocation.x, LastLocation.y); 
CGContextAddLineToPoint(ctx, Current.x, Current.y); 
CGContextStrokePath(ctx); 
/* Push the updated graphics back to the image */ 
drawImage.image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

'drawImage.image drawInRect'호출이 매우 느리고 본질적으로 전체 이미지를 다시 그립니다.

더 빠른 방법이 있나요? 그림 그리기를 위해 블로그의 몇 군데에서 이와 같은 코드를 그리는 것을 보았습니다.하지만 약간 느립니다. 주제에 대한 의견을 듣고 싶습니다.

+0

Fuzz,이 작업을 수행 했습니까? 나는 매우 비슷한 문제를 찾아 내려고 노력하고있다. 당신이 생각한 것을 듣고 싶습니다. 고마워요 - fxshot –

답변

1

수동으로 이미지와 선을 합성 할 필요가 없습니다. 뷰를 통해 이미지를 그리는 다른 UIImageView 위에 선을 그립니다. 시스템에서 합성 작업을 수행하고 이미지를 그립니다.

코드에서 선 그리기보기의 drawRect : 메서드에있는 두 개의 drawImage 선 사이에있는 내용 만 수행하면됩니다.

-(void) drawRect:(CGRect)dirty { 
    CGContextRef ctx = UIGraphicsGetCurrentContext(); 
    /* Set line draw color to green, rounded cap end and width of 5 */ 
    CGContextSetLineDash(ctx, 0, dashPattern, 2); 
    CGContextSetStrokeColorWithColor(ctx, color); 
    CGContextSetLineCap(ctx, kCGLineCapRound); //kCGLineCapSquare, kCGLineCapButt, kCGLineCapRound 
    CGContextSetLineWidth(ctx, 5.0); // for size 
    /* Start the new path point */ 
    CGContextMoveToPoint(ctx, LastLocation.x, LastLocation.y); 
    CGContextAddLineToPoint(ctx, Current.x, Current.y); 
    CGContextStrokePath(ctx); 
} 

줄의 한쪽 끝이 이동하면 새 지점을 저장하고 표시해야 할 줄 그림을 표시하십시오. 따라서 Current와 LastLocation은 모두 선 그리기보기의 멤버 여야하며 각 setter 메서드에서 setNeedsDisplay를 호출합니다.

선 그리기보기에서 clearsContextBeforeDrawing이 YES이고 불투명도가 NO인지 확인하십시오.

+0

drawnonward, 나는 당신의 솔루션에 대해 생각해 봤는데 내가 제대로 자아를 설명했는지 확신 할 수 없으므로 질문을 업데이트 할 것입니다. UIImageView는 컨텍스트가 항상 새로 고쳐지기 때문에 사용자가 화면에 그린 선만 유지합니다. 내가 실제로하려고하는 효과는 사용자 손가락으로 "페인트 브러시"스타일 움직임과 같으며 모든 그림은 계속 유지됩니다. 그 지속성을 유지하기 위해 UIImageView를 사용하고있었습니다. 말이 돼? :-) – Fuzz

+0

현재 코드는 매 호출시에 UIGraphicsBeginImageContext를 사용하여 새로운 CGBitmapContext를 만든 다음 해당 컨텍스트의 내용을 UIGraphicsGetImageFromCurrentImageContext를 사용하여 새 이미지에 복사합니다. 이는 불필요한 많은 데이터가 복사되는 것입니다. 대신 하나의 영구 CGBitmapContext를 만들고 동일한 픽셀을 참조하는 하나의 CGImage를 만들어야합니다. 그런 다음 해당 이미지를 drawRect :에 그리거나 UIImageView에 붙여 넣습니다. 비트 맵이 변경 될 때마다 뷰에서 setNeedsDisplay를 호출하십시오. – drawnonward

+0

아, 굉장합니다. 말이된다. 나는 그것을 풀려고 얼마 동안 노력했지만, 어떻게 CGBitmapContext와 같은 메모리로 CGImage를 만들 수 있습니까? 나는 컨텍스트를 만들었고 데이터를 얻기에 충분히 큰 무언가를 가지고있다. 그러나 나는 CGImage를 만드는 방법을 모른다. CGBitmapContextCreate를 사용하면 실제로 복사가되므로 도움이되지 않습니다 .- ( – Fuzz

관련 문제