5

図面に「エンボス/シャドウ効果」を実装する際に問題があります。フィンガー ペイント機能は現在、私のカスタムで正常に動作してUIViewおり、以下は私のdrawRectメソッド コードです。

すべてのメソッドでコードを編集します:

- (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];

}

これを実装すると、ドットドットドットでペイント効果が得られます...

下の画像を参照してください (影やエンボス効果はありません)。これらの効果を追加する方法について何か考えがある場合は、提案をお願いします。どうすればこれを解決できますか?

ここに画像の説明を入力

4

3 に答える 3

4

各drawRectに1つずつ、数百、場合によっては数千もの個別のパスを作成しているようです。あなたはこれらを使って平ら[self.layer renderInContext]にしますが、それはそれについて行くのに良い方法ではないと思います。代わりに、指を追跡するUIBezierPathを1つ作成し、それにパスを追加して、UIBezierPathを画面に描画することをお勧めします。2つのレイヤー(またはビュー)を作成する場合は、一番上のレイヤー(透明)を「描画」するように設定できます。ユーザーが指を離すと、UIBezierPath全体が(以前に描画されたデータとともに)2番目のレイヤーにレンダリングされ、次の指追跡を描画するための新しいUIBezierPathが作成されます。このようにして、誰かの指を追跡しているときに1つのレイヤー(一番上のレイヤー)のみを更新します。これにより、デバイスがあまりにも多くのパスを描画する速度が低下するのを防ぐことができます。

ただし、現在の方法では、かっこいい「3D」効果が得られます。

于 2012-06-22T12:49:23.193 に答える
0

エンボス加工についてはよくわかりませんが、段階的に更新される図面にドロップシャドウを適用する場合は、CALayers(チュートリアルへのリンク)を使用することをお勧めします。基本的に、プログレッシブ描画は透明な画像を更新し(この画像に影を描画しようとせずに)、この画像はCALayerを介してドロップシャドウで表示されるように構成されます。

于 2012-06-22T12:58:10.220 に答える
0

境界線に影が作成され、線の小さなセグメントを描画すると、この効果が作成されます。パスを作成してから、一度ストロークする必要があります。このコードはあなたを助けるかもしれません:)

for (int i=0; i<[currentPath count]; i++) 
{
    CGPoint mid1 = [[self midPoint:[currentPath objectAtIndex:i+1]  :[currentPath objectAtIndex:i]] CGPointValue]; 
    CGPoint mid2 = [[self midPoint:[currentPath objectAtIndex:i+2] :[currentPath objectAtIndex:i+1]] CGPointValue];
    CGContextMoveToPoint(context, mid1.x, mid1.y);
    CGContextAddQuadCurveToPoint(context, [[currentPath objectAtIndex:i+1] CGPointValue].x, [[currentPath objectAtIndex:i+1] CGPointValue].y, mid2.x, mid2.y); 
    CGContextSetShadow(context, CGSizeMake(-2, -2), 3);

    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetStrokeColorWithColor(context,[color CGColor]);              
    CGContextSetLineWidth(context, linewidth);              

    i+=2;
}
CGContextStrokePath(context);

この方法を試してください..これで問題が解決する可能性があります..最初にurパスを作成し、完全に作成した後、それをストロークします。これは、ストロークするすべての小さな線で発生し、作成された影がその境界にドットを作成するため、この効果が得られます。

于 2012-06-25T04:50:44.693 に答える