Jak kreslit transparentní mrtvice (nebo v každém případě jasné část obrazu) na iPhone

hlasů
18

Mám malý aplikace, která umožňuje uživateli kreslit na obrazovce prstem. Mám UIImageViewkde uživatel čerpá, tím, že vytvoří CGContextRefa různé CG drawfunkce. I primárně čerpat zdvihy / řádky s funkcíCGContextAddLineToPoint

Teď moje otázka je následující: Uživatel může kreslit čáry různých barev. Chci mu dát možnost použít rubbernástroj odstranit určitou část obrazu dosud vypracované s prstem. Původně jsem to udělal pomocí bílou barvu pro cévní mozkové příhody (nastavit pomocí CGContextSetRGBStrokeColorfunkcí), ale to nevyšlo ... protože jsem zjistil později, že UIImagena UIImageViewskutečně měl průhledné pozadí, ne bílá ... tak bych skončit s transparentní obraz s bílými pruhy na to!

Je tam tak jako tak nastavit transparentbarvu tahu nebo je nějaký jiný způsob, jak vymazat obsah z CGContextRefpod prstem uživatele, když ji přesune? dík

Položena 10/03/2009 v 10:18
zdroj uživatelem
V jiných jazycích...                            


6 odpovědí

hlasů
57

To bude stačit:

CGContextSetBlendMode(context, kCGBlendModeClear)
Odpovězeno 27/04/2010 v 19:29
zdroj uživatelem

hlasů
6

Skončil jsem s použitím bresenhamův algoritmus (harkening zpět do dávných dobách, kdy jsem musel psát své vlastní grafické rutiny) ...

- (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);
        }
    }
}

Uf! To je dlouhá cesta k vytvoření (poněkud) neohrabaný guma linku.

Pokud jej chcete použít, něco jako:

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

To předpokládá, že jste již vytvořili drawingView (UIImageView) a drawingBoard (UIImage).

Poté vymazat čáru, prostě něco takového:

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

(Nahradí X1, Y1, X2, ay2 s příslušnými hodnotami) ...

Odpovězeno 04/04/2009 v 06:33
zdroj uživatelem

hlasů
1

Snažil jsem se pomocí:

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

ale to nebude fungovat, protože se zdá, že „čerpání“ v horní části souvislosti s neviditelnou barvou (a neviditelné barvy + bez ohledu na barvu je kreslení na = barevném to čerpání).

Jediné řešení jsem našel (což není optimální) je:

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

Bohužel, to znamená, že musíte sledovat řadu rects a vytvářet čáru sami ...

Odpovězeno 30/03/2009 v 21:59
zdroj uživatelem

hlasů
0

Chcete-li vymazat obrázek s nádechem to je můj kód .... Jistý díl nedoporučuje to funguje, ale poněkud pomalý.

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

}
Odpovězeno 28/03/2019 v 14:01
zdroj uživatelem

hlasů
-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;
}
}
Odpovězeno 24/08/2011 v 16:25
zdroj uživatelem

hlasů
-13
UIColor *clearColor = [UIColor clearColor];
Odpovězeno 10/03/2009 v 15:07
zdroj uživatelem

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