如何使用Core Graphics创建浮雕或阴影效果(用于手指画) [英] How to create embossed or shadow effects using Core Graphics (for finger paint)

查看:381
本文介绍了如何使用Core Graphics创建浮雕或阴影效果(用于手指画)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有问题在我的绘图中实现浮雕/阴影效果。我的自定义 UIView 目前手指绘画功能正常工作,下面是我的 drawRect 方法代码:

I have issue to implement "Emboss/Shadow effects" in my drawing. Finger paint functionality is currently working fine with my custom UIView and below is my drawRect method code:

使用所有方法编辑代码:

- (void)drawRect:(CGRect)rect
{
    CGPoint mid1 = midPoint(previousPoint1, previousPoint2); 
    CGPoint mid2 = midPoint(currentPoint, previousPoint1);

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    [self.layer renderInContext:context];

    CGContextMoveToPoint(context, mid1.x, mid1.y);
    CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y); 
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineWidth(context, self.lineWidth);
    CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
    CGContextSaveGState(context);

    // for shadow  effects
    CGContextSetShadowWithColor(context, CGSizeMake(0, 2),3, self.lineColor.CGColor);
    CGContextStrokePath(context);
    [super drawRect:rect];
}

CGPoint midPoint(CGPoint p1, CGPoint p2)
{
    return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5);
}


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    UITouch *touch = [touches anyObject];

    previousPoint1 = [touch previousLocationInView:self];
    previousPoint2 = [touch previousLocationInView:self];
    currentPoint = [touch locationInView:self];

    [self touchesMoved:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

    UITouch *touch  = [touches anyObject];

    previousPoint2  = previousPoint1;
    previousPoint1  = [touch previousLocationInView:self];
    currentPoint    = [touch locationInView:self];


    // calculate mid point
    CGPoint mid1    = midPoint(previousPoint1, previousPoint2); 
    CGPoint mid2    = midPoint(currentPoint, previousPoint1);

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
    CGPathAddQuadCurveToPoint(path, NULL, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
    CGRect bounds = CGPathGetBoundingBox(path);
    CGPathRelease(path);

    CGRect drawBox = bounds;

    //Pad our values so the bounding box respects our line width
    drawBox.origin.x        -= self.lineWidth * 2;
    drawBox.origin.y        -= self.lineWidth * 2;
    drawBox.size.width      += self.lineWidth * 4;
    drawBox.size.height     += self.lineWidth * 4;

    UIGraphicsBeginImageContext(drawBox.size);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    curImage = UIGraphicsGetImageFromCurrentImageContext();
    [curImage retain];
    UIGraphicsEndImageContext();



   [self setNeedsDisplayInRect:drawBox];

}

当我实现这个时,我得到了带点的油漆效果点点...

when i have implemented this i am getting paint effects with dot dot dot ...

见下图(没有任何阴影或浮雕效果)。如果您对如何添加这些效果有任何想法,请给我一些建议。我该如何解决这个问题?

See below image (which does not have any shadow or embossed effects). If you have any idea of how to add these effects, please give me some suggestion. How can i resolve this?

推荐答案

看来你在每个drawRect上创建了数百个甚至数千个单独的路径。你确实使用 [self.layer renderInContext] 来展平这些,但我认为这不是一个很好的方法。相反,我认为你想要做的是创建一个UIBezierPath来跟踪手指,将路径附加到该手指并将UIBezierPath绘制到屏幕上。如果创建两个图层(或视图),则可以将顶部(透明)设置为绘制。当用户抬起手指时,然后将整个UIBezierPath渲染到第二层(以及先前绘制的数据)并创建新的UIBezierPath以绘制下一个手指跟踪。这样,当您跟踪某人的手指时,您只会更新一个图层(顶部图层)。这有助于防止设备减慢绘制太多路径的速度。

It appears that you're creating hundreds, maybe even thousands of separate paths, one on each drawRect. You do flatten these out using [self.layer renderInContext] but I don't think that's a good way to go about it. Instead, I think what you want to do is create one UIBezierPath to track the finger, append paths to that and draw the UIBezierPath to the screen. If you create two layers (or views) you can set the top one (transparent) to "draw" on. When the user lifts their finger, you then render the entire UIBezierPath to the second layer (along with previously drawn data) and create a new UIBezierPath to draw the next finger-tracking. This way you're only updating one layer (the top one) when you're tracking someone's finger. This will help prevent the device from slowing down drawing too many paths.

虽然,我会说,你现在的方法确实会产生很酷的3D效果。

Although, I will say, your current method does produce a cool looking "3D" effect.

这篇关于如何使用Core Graphics创建浮雕或阴影效果(用于手指画)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆