كيفية رسم شفاف السكتة الدماغية (أو على أي حال من الواضح جزء من صورة) على اي فون

StackOverflow https://stackoverflow.com/questions/629409

  •  08-07-2019
  •  | 
  •  

سؤال

يجب تطبيق صغير الذي يسمح للمستخدم رسم على الشاشة مع الاصبع.لدي UIImageView حيث توجه المستخدم ، عن طريق إنشاء CGContextRef ومختلف CG draw المهام.أنا في المقام الأول رسم خطوط/خطوط مع وظيفة CGContextAddLineToPoint

الآن مشكلتي هي هذه:يمكن للمستخدم رسم خطوط من الألوان المختلفة.أريد أن يعطيه القدرة على استخدام "rubber" أداة حذف جزء من صورة رسمها حتى الآن مع الاصبع.أنا في البداية لم هذا باستخدام اللون الأبيض عن السكتة الدماغية (مجموعة مع CGContextSetRGBStrokeColor وظيفة) ولكنه لم ينجح لأن اكتشفت لاحقا أن UIImage على UIImageView كان في الواقع خلفية شفافة ، وليس الأبيض...لذلك أنا في نهاية المطاف مع صورة شفافة مع خطوط بيضاء على ذلك!

هناك على أية حال تعيين "transparent" السكتة الدماغية اللون أو هل هناك أي طريقة أخرى لمسح محتوى CGContextRef تحت إصبع المستخدم ، وعندما يتحرك ؟ شكرا

هل كانت مفيدة؟

المحلول

وهذا سوف تفعل خدعة:

CGContextSetBlendMode(context, kCGBlendModeClear)

نصائح أخرى

وانتهى بي الأمر باستخدام خوارزمية بريزنهام لرسم مستقيم (harkening العودة إلى أيام من ماض عندما أتيحت لي لكتابة حركاتي الرسومات الخاصة) ...

- (void) contextEraseLine:(CGContextRef) ctx from:(CGPoint)startPoint to:(CGPoint) endPoint withThickness:(int)thickness {
    int x, cx, deltax, xstep,
    y, cy, deltay, ystep,
    error, st, dupe;

    int x0, y0, x1, y1;

    x0 = startPoint.x;
    y0 = startPoint.y;
    x1 = endPoint.x;
    y1 = endPoint.y;

    // find largest delta for pixel steps
    st = (abs(y1 - y0) > abs(x1 - x0));

    // if deltay > deltax then swap x,y
    if (st) {
        (x0 ^= y0); (y0 ^= x0); (x0 ^= y0); // swap(x0, y0);
        (x1 ^= y1); (y1 ^= x1); (x1 ^= y1); // swap(x1, y1);
    }

    deltax = abs(x1 - x0);
    deltay = abs(y1 - y0);
    error  = (deltax / 2);
    y = y0;

    if (x0 > x1) { xstep = -1; }
    else         { xstep =  1; }

    if (y0 > y1) { ystep = -1; }
    else         { ystep =  1; }

    for ((x = x0); (x != (x1 + xstep)); (x += xstep))
    {
        (cx = x); (cy = y); // copy of x, copy of y

        // if x,y swapped above, swap them back now
        if (st) { (cx ^= cy); (cy ^= cx); (cx ^= cy); }

        (dupe = 0); // initialize no dupe

        if(!dupe) { // if not a dupe, write it out
            //NSLog(@"(%2d, %2d)", cx, cy);

            CGContextClearRect(ctx, CGRectMake(cx, cy, thickness, thickness));

    }

        (error -= deltay); // converge toward end of line

        if (error < 0) { // not done yet
            (y += ystep);
            (error += deltax);
        }
    }
}

وتفو! هذا هو طريق طويل لنقطعه لإنشاء (إلى حد ما) عالي الكعب خط ممحاة.

لاستخدامها، لا شيء مثل:

- (void)eraseStart {
    // erase lines
    UIGraphicsBeginImageContext(drawingBoard.size);
    ctx = UIGraphicsGetCurrentContext();
    CGContextDrawImage(ctx,CGRectMake(0,0,drawingBoard.size.width, drawingBoard.size.height),[drawingBoard CGImage]); 
}

- (void)eraseEnd {
    drawingBoard = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    [drawingView removeFromSuperview];
    [drawingView release];

    drawingView = [[UIImageView alloc] initWithImage:drawingBoard];
    drawingView.frame = CGRectMake(intEtchX, intEtchY, intEtchWidth, intEtchHeight);

    [self.view addSubview:drawingView];
}

وهذا يفترض أنك قد قمت بالفعل بإنشاء drawingView (UIImageView) وdrawingBoard (UIImage).

وبعد ذلك، لمحو خط، فلا تفعل شيئا مثل:

CGContextRef ctx = UIGraphicsGetCurrentContext();
[self eraseStart];
[self contextEraseLine:ctx from:CGPointMake (x1, y1) to:CGPointMake (x2, y2) withThickness:10];
[self eraseEnd];

و(استبدال X1، Y1، X2، Y2 ومع القيم المناسبة) ...

لقد حاولت استخدام:

CGContextSetStrokeColorWithColor (myContext, [[UIColor clearColor] CGColor]);

ولكن هذا لا يعمل, لأنه يبدو أن "الرسم" على رأس السياق مع غير مرئية اللون (غير مرئية اللون + أي لون هو الرسم على = اللون هو الرسم على).

الحل الوحيد لقد وجدت (وهي ليست الأمثل) هو:

CGContextClearRect (myContext, CGRectMake(x, y, width, height));

للأسف, هذا يعني أن عليك أن تتبع سلسلة من rects وتوليد الخط نفسك...

إذا كنت تريد أن تمحو صورة مع لمسة وهذا هو قانون بلدي .... الجزء نيراسي لا ينصح أنها تعمل ولكن بطيئة قليلا.

func addNewPathToImage(){
    print("Start erasing or not erasing")

    UIGraphicsBeginImageContextWithOptions(TopImageUIImageView.bounds.size, false, UIScreen.main.scale) // or 0 for the scale

//My image is aspect fit so I need to get rect

    let aspect = TopImageUIImageView.image!.size.width / TopImageUIImageView.image!.size.height
    let viewRatio = TopImageUIImageView.bounds.size.width / TopImageUIImageView.bounds.size.height


    if aspect < viewRatio {
        let scale = TopImageUIImageView.bounds.size.height / TopImageUIImageView.image!.size.height
        let width = scale * TopImageUIImageView.image!.size.width
        let topLeftX = (TopImageUIImageView.bounds.size.width - width) * 0.5
        rect = CGRect(x: topLeftX, y: 0, width: width, height: TopImageUIImageView.bounds.size.height)
    }
    else {
        let scale = TopImageUIImageView.bounds.size.width / TopImageUIImageView.image!.size.width
        let height = scale * TopImageUIImageView.image!.size.height
        let topLeftY = (TopImageUIImageView.bounds.size.height - height) * 0.5
        rect = CGRect(x: 0.0, y: topLeftY, width: TopImageUIImageView.bounds.size.width, height: height)
    }
    ////
    context = UIGraphicsGetCurrentContext()
    TopImageUIImageView.image?.draw(in: rect)
    context?.setLineCap(.round)
    context?.setLineWidth(brushSize)



    if isErasing == true {

        context?.setShadow(offset: CGSize(width: 0, height: 0), blur: blurNumber)
        context?.setStrokeColor(UIColor.white.cgColor)
        context?.setBlendMode(.clear)


    }else{

        print("test the unerase image .... ?")
        context?.setStrokeColor(UIColor.init(patternImage: topImage.af_imageAspectScaled(toFit: CGSize(width: TopImageUIImageView.bounds.size.width, height: TopImageUIImageView.bounds.size.height))).cgColor)

    }


   // I am using these because I am using touch to define what to erase 
        context?.move(to: CGPoint(x: lastTouch.x, y: lastTouch.y))
        context?.addLine(to: CGPoint(x: currentTouch.x, y: currentTouch.y))
        context?.strokePath()
        context?.closePath() // when add this line or the "context?.beginPath" get ERROR CGContextClosePath: no current point.
        print("close the path")




        //get your image 
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        TopImageUIImageView.image = image

}
//erase part
if(mouseSwiped)
{

//**************Working Code*************// 


UIGraphicsBeginImageContext(frontImage.frame.size);
[frontImage.image drawInRect:CGRectMake(0, 0, frontImage.frame.size.width, frontImage.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(),kCGImageAlphaNone); //kCGImageAlphaPremultipliedLast);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 10);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1, 0, 0, 10);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextClearRect (UIGraphicsGetCurrentContext(), CGRectMake(lastPoint.x, lastPoint.y, 10, 10));
CGContextStrokePath(UIGraphicsGetCurrentContext());
frontImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();


lastPoint = currentPoint;

mouseMoved++;

if (mouseMoved == 10) 
{
    mouseMoved = 0;
}
}
UIColor *clearColor = [UIColor clearColor];
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top