问题
We are working on a paint application using UIBezierPath
,
We did paint strokes using bezier path,
with blue color RGB values and 0.5 Alpha for transparent stroke
using paths array.. we almost complete the application,
But there are some performance issues to drayong paint strokes from PathsArray which is having alredy drawn Bezierpaths, like paint strokes getting slow after drawing some number of strokes,
So to avoid this performance issue we used an temperary image view behind the sketchImage View,
We drawn recent one stroke on Top Sketch Image view and updated the bottom Temperary iamge view with the PathsArray,
it works fine and imrove performance, but there is an issue
that since all the strokes saved as image and we try to draw another image the strokes gets double and increase the opacity at overlaping points
actually we can avoid if we use only bezierPAths array using kCGBlendModeCopy
But since we are updated stroke as image its not able with kCGBlendModeCopy
So is there any way to avoid stroke on same paint
回答1:
You can achieve the desired effect by having two image views, the landscape photo in one, and on top of that, another image view upon which we're going to draw. But, rather than drawing with an alpha
of 0.5, draw a UIBezierPath
with alpha
of 1.0, but do it on an image view whose own alpha
is 0.5.
- (void)handlePan:(UIPanGestureRecognizer *)gesture
{
static UIBezierPath *bezierPath = nil;
static CAShapeLayer *shapeLayer = nil;
if (gesture.state == UIGestureRecognizerStateBegan) {
bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint:[gesture locationInView:gesture.view]];
shapeLayer = [CAShapeLayer layer];
shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
shapeLayer.lineWidth = 40.0;
shapeLayer.fillColor = [[UIColor clearColor] CGColor];
shapeLayer.lineCap = kCALineCapRound;
shapeLayer.lineJoin = kCALineJoinRound;
[self.drawImageView.layer addSublayer:shapeLayer];
} else if (gesture.state == UIGestureRecognizerStateChanged) {
[bezierPath addLineToPoint:[gesture locationInView:gesture.view]];
shapeLayer.path = [bezierPath CGPath];
} else if (gesture.state == UIGestureRecognizerStateEnded) {
CGFloat saveAlpha = self.drawImageView.alpha; // save current alpha for future reference
self.drawImageView.alpha = 1.0; // bring alpha back to 1.0 for the purposes of saving image
// grab image
UIGraphicsBeginImageContextWithOptions(self.drawImageView.bounds.size, NO, 0);
if ([self.drawImageView respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)])
[self.drawImageView drawViewHierarchyInRect:self.drawImageView.bounds afterScreenUpdates:YES]; // iOS7+
else
[self.drawImageView.layer renderInContext:UIGraphicsGetCurrentContext()]; // pre iOS7
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.drawImageView.image = image; // use new image
self.drawImageView.alpha = saveAlpha; // reduce alpha back to what it was
[shapeLayer removeFromSuperlayer]; // get rid of shape layer
shapeLayer = nil;
bezierPath = nil;
}
}
回答2:
- (UIImage*)addImage:(UIImage *)image secondImage:(UIImage *)image2
{
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
[image2 drawInRect:CGRectMake(0,0,image.size.width,image.size.height) blendMode:kCGBlendModeXOR alpha:1.0];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Adding two UIImages use the above code. in blendMode
use kCGBlendModeXOR
.
来源:https://stackoverflow.com/questions/20263379/objective-c-how-to-avoid-drawing-on-same-color-image-having-stroke-color-of-uibe