Πώς να σχεδιάσετε ένα διαφανές εγκεφαλικό επεισόδιο (ή τέλος πάντων σαφές μέρος της εικόνας) για το iPhone

ψήφοι
18

Έχω μια μικρή εφαρμογή που επιτρέπει στο χρήστη να ζωγραφίζετε στην οθόνη με το δάχτυλο. Έχω ένα UIImageViewόπου ο χρήστης αντλεί, με τη δημιουργία ενός CGContextRefκαι των διαφόρων CG drawλειτουργιών. Έχω κυρίως επιστήσω την πινελιές / γραμμές με τη λειτουργίαCGContextAddLineToPoint

Τώρα το θέμα μου είναι το εξής: Ο χρήστης μπορεί να αντλήσει γραμμές σε διάφορα χρώματα. Θέλω να του δώσει τη δυνατότητα να χρησιμοποιήσετε ένα rubberεργαλείο για να διαγράψει κάποιο τμήμα της εικόνας που μέχρι τώρα, με το δάχτυλο. Εγώ αρχικά το έκανε αυτό, χρησιμοποιώντας ένα λευκό χρώμα για το εγκεφαλικό επεισόδιο (που με τη CGContextSetRGBStrokeColorλειτουργία του), αλλά δεν δούλεψε ... γιατί ανακάλυψα αργότερα ότι η UIImageσχετικά με την UIImageViewπραγματικότητα είχε ένα διαφανές φόντο, όχι άσπρο ... γι 'αυτό θα καταλήξουμε σε μια διαφανή εικόνα με λευκές γραμμές σε αυτό!

Είναι ούτως ή άλλως εκεί για να ορίσετε ένα transparentχρώμα εγκεφαλικό επεισόδιο ή υπάρχει άλλος τρόπος για να καθαρίσετε το περιεχόμενο του CGContextRefκάτω από το δάχτυλό του χρήστη, όταν αυτός κινείται; Ευχαριστώ

Δημοσιεύθηκε 10/03/2009 στις 10:18
πηγή χρήστη
Σε άλλες γλώσσες...                            


6 απαντήσεις

ψήφοι
57

Αυτό θα κάνει το κόλπο:

CGContextSetBlendMode(context, kCGBlendModeClear)
Απαντήθηκε 27/04/2010 στις 19:29
πηγή χρήστη

ψήφοι
6

Κατέληξα να χρησιμοποιούν τον αλγόριθμο γραμμή Bresenham του (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 και με κατάλληλες τιμές) ...

Απαντήθηκε 04/04/2009 στις 06:33
πηγή χρήστη

ψήφοι
1

Έχω δοκιμάσει τη χρήση:

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

αλλά αυτό δεν λειτουργεί, επειδή φαίνεται να «σύνταξη» πάνω από το πλαίσιο με ένα αόρατο χρώμα (και αόρατο χρώμα + ό, τι χρώμα είναι αντλώντας = το χρώμα είναι αντλώντας).

Η μόνη λύση που έχω βρεθεί (η οποία δεν είναι η βέλτιστη) είναι:

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

Δυστυχώς, αυτό σημαίνει ότι θα πρέπει να εντοπίζουν μια σειρά από rects και να δημιουργήσει τη γραμμή μόνοι σας ...

Απαντήθηκε 30/03/2009 στις 21:59
πηγή χρήστη

ψήφοι
0

Αν θέλετε να διαγράψετε εικόνας με την αφή αυτό τον κωδικό μου .... το μέρος unerase δεν συνιστάται να λειτουργεί, αλλά λίγο αργή.

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

}
Απαντήθηκε 28/03/2019 στις 14:01
πηγή χρήστη

ψήφοι
-2
//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;
}
}
Απαντήθηκε 24/08/2011 στις 16:25
πηγή χρήστη

ψήφοι
-13
UIColor *clearColor = [UIColor clearColor];
Απαντήθηκε 10/03/2009 στις 15:07
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more