2014-03-02 55 views
3

我正在關注我的塗鴉應用程序的本教程。iOS Core Graphics如何清除圖形

http://www.raywenderlich.com/18840/how-to-make-a-simple-drawing-app-with-uikit

他擦除功能是用白色繪製。但我正在使用圖像背景,當我擦除時,我真的需要擦除。

我已經試過

CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear); 

但它不工作。這裏是我的代碼:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    _mouseSwiped = NO; 
    UITouch *touch = [touches anyObject]; 
    _lastPoint = [touch locationInView:self.tempImageView]; 
} 

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

    _mouseSwiped = YES; 
    UITouch *touch = [touches anyObject]; 
    CGPoint currentPoint = [touch locationInView:self.tempImageView]; 

    UIGraphicsBeginImageContext(self.tempImageView.frame.size); 
    [self.tempImageView.image drawInRect:CGRectMake(0, 0, self.tempImageView.frame.size.width, self.tempImageView.frame.size.height)]; 
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), _lastPoint.x, _lastPoint.y); 
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y); 
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); 
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), _width); 


    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), _red, _green, _blue, 1.0); 

    if (_isErasing) { 
     CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear); 
    } 
    else { 
     CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal); 
    } 

    CGContextStrokePath(UIGraphicsGetCurrentContext()); 
    self.tempImageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
    [self.tempImageView setAlpha:_alpha]; 
    UIGraphicsEndImageContext(); 

    _lastPoint = currentPoint; 
} 

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

    CGSize size = self.tempImageView.frame.size; 

    if(!_mouseSwiped) { 
     UIGraphicsBeginImageContext(self.tempImageView.frame.size); 
     [self.tempImageView.image drawInRect:CGRectMake(0, 0, size.width, size.height)]; 
     CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); 
     CGContextSetLineWidth(UIGraphicsGetCurrentContext(), _width); 


     CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), _red, _green, _blue, _alpha); 
     CGContextMoveToPoint(UIGraphicsGetCurrentContext(), _lastPoint.x, _lastPoint.y); 
     CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), _lastPoint.x, _lastPoint.y); 
     CGContextStrokePath(UIGraphicsGetCurrentContext()); 
     CGContextFlush(UIGraphicsGetCurrentContext()); 
     self.tempImageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 
    } 




    UIGraphicsBeginImageContext(self.drawImageView.frame.size); 
    [self.drawImageView.image drawInRect:CGRectMake(0, 0, size.width, size.height) blendMode:kCGBlendModeNormal alpha:1.0]; 

    if (_isErasing) { 
     CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear); 
    } 

    [self.tempImageView.image drawInRect:CGRectMake(0, 0, self.tempImageView.frame.size.width, self.tempImageView.frame.size.height) blendMode:kCGBlendModeNormal alpha:_alpha]; 


    self.drawImageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
    self.tempImageView.image = nil; 
    UIGraphicsEndImageContext(); 
} 

回答

5

通過交換tempImageView和drawImageView解決了這個問題,當觸摸開始,如果是刪除

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    _mouseSwiped = NO; 
    UITouch *touch = [touches anyObject]; 
    _lastPoint = [touch locationInView:self.tempImageView]; 

    if (_isErasing) { 
     self.tempImageView.image = self.drawImageView.image; 
     self.drawImageView.image = nil; 
    } 

} 



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

    _mouseSwiped = YES; 
    UITouch *touch = [touches anyObject]; 
    CGPoint currentPoint = [touch locationInView:self.tempImageView]; 

    UIGraphicsBeginImageContext(self.tempImageView.frame.size); 
    [self.tempImageView.image drawInRect:CGRectMake(0, 0, self.tempImageView.frame.size.width, self.tempImageView.frame.size.height)]; 
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), _lastPoint.x, _lastPoint.y); 
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y); 
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); 
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), _width); 


    if (_isErasing) { 
     CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear); 
    } 
    else { 
     CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), _red, _green, _blue, 1.0); 
     CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal); 
    } 

    CGContextStrokePath(UIGraphicsGetCurrentContext()); 
    self.tempImageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
    [self.tempImageView setAlpha:_alpha]; 
    UIGraphicsEndImageContext(); 

    _lastPoint = currentPoint; 
} 





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

    CGSize size = self.tempImageView.frame.size; 

    if(!_mouseSwiped) { 
     UIGraphicsBeginImageContext(self.tempImageView.frame.size); 
     [self.tempImageView.image drawInRect:CGRectMake(0, 0, size.width, size.height)]; 
     CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); 
     CGContextSetLineWidth(UIGraphicsGetCurrentContext(), _width); 


     if (_isErasing) { 
      CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear); 
     } 
     else { 
      CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), _red, _green, _blue, _alpha); 
      CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal); 
     } 

     CGContextMoveToPoint(UIGraphicsGetCurrentContext(), _lastPoint.x, _lastPoint.y); 
     CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), _lastPoint.x, _lastPoint.y); 
     CGContextStrokePath(UIGraphicsGetCurrentContext()); 
     CGContextFlush(UIGraphicsGetCurrentContext()); 
     self.tempImageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 
    } 




    UIGraphicsBeginImageContext(self.drawImageView.frame.size); 
    [self.drawImageView.image drawInRect:CGRectMake(0, 0, size.width, size.height) blendMode:kCGBlendModeNormal alpha:1.0]; 
    [self.tempImageView.image drawInRect:CGRectMake(0, 0, size.width, size.height) blendMode:kCGBlendModeNormal alpha:_alpha]; 
    self.drawImageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
    self.tempImageView.image = nil; 
    UIGraphicsEndImageContext(); 
} 
+0

爲什麼交換tempImage和drawingImage?只是好奇? – 2017-01-05 18:12:27

-1

爲什麼不在一個單獨的視圖上繪畫/繪圖?

TopView = Paint + gesture ....,BottomView =背景圖像。

擦色= ClearColor(透明)

最後,如果你想儲存您的作品,你來兩張圖片結合起來。

+0

的教程中指出,這是更簡單的有2次處理不透明 – OMGPOP

+0

「你可以,但雙的UIImageViews被用來保存opacity。當你在tempDrawImage上繪圖時,不透明度被設置爲1.0(完全不透明)。但是,當你將tempDrawImage和mainImage合併時,tempDrawImage的不透明度被設置爲配置值,因此給畫筆描邊賦予了我們想要的不透明度。如果您直接在mainImage上繪圖,使用不同的不透明度值繪製筆觸將非常困難。「 – OMGPOP

1

如果有人仍然intereted這是怎麼在斯威夫特工作對我來說3.感謝您的幫助OMGPOP

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    swiped = false 
    hideAllButtons() 
    if let touch = touches.first { 
     lastPoint = touch.location(in: self.view) 
    } 

    if isErasing { 
     self.tempImageView.image = self.mainImageView.image 
     self.mainImageView.image = nil 
    } 
} 

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
    swiped = true 
    if let touch = touches.first { 
     let currentPoint = touch.location(in: view) 
     drawLineFrom(fromPoint: lastPoint, toPoint: currentPoint) 

     lastPoint = currentPoint 
    } 

} 

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 
    showAllButtons() 
    if !swiped { 
     drawLineFrom(fromPoint: lastPoint, toPoint: lastPoint) 
    } 

    UIGraphicsBeginImageContext(mainImageView.frame.size) 
    mainImageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: .normal, alpha: 1.0) 
    tempImageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: .normal, alpha: opacity) 
    mainImageView.image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    tempImageView.image = nil 
} 

// Draws a line between two points on the view 
func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) { 
    UIGraphicsBeginImageContext(view.frame.size) 
    let context = UIGraphicsGetCurrentContext() 
    tempImageView.image?.draw(in: CGRect(x:0, y:0, width: view.frame.size.width, height: view.frame.size.height)) 

    context?.move(to: fromPoint) 
    context?.addLine(to: toPoint) 

    context?.setLineCap(.round) 
    context?.setLineWidth(brushWidth) 

    if isErasing { 
     context?.setBlendMode(.clear) 
    } else { 
     context?.setStrokeColor(red: red, green: green, blue: blue, alpha: 1.0) 
     context?.setBlendMode(.normal) 
    } 
    context?.strokePath() 

    tempImageView.image = UIGraphicsGetImageFromCurrentImageContext() 
    tempImageView.alpha = opacity 
    UIGraphicsEndImageContext() 

} 
+0

這不起作用。它創造像我的問題的問題http://stackoverflow.com/questions/43137955/image-gets-blurry-and-zoomed-out-when-erasing –

0

下面是我如何獲得橡皮擦的工作。 在touchesEnded功能我畫上用下面的代碼上下文:

//draw the main image on the context 
self.mainImage.image?.draw(in: CGRect(x:0, y:0, width:self.view.frame.size.width, height:self.view.frame.size.height), blendMode: .normal, alpha: 1.0) 
    if(erasing == false) { 
     //draw the current stroke normally since we're not erasing 
     self.tempDrawImage.image?.draw(in: CGRect(x:0, y:0, width:self.view.frame.size.width, height:self.view.frame.size.height), blendMode: .normal, alpha: opacity!) 
    } else { 
     //let's create a mask of what we would like to erase by using the destinationIn function which according to the docs is the following 
     //R = D*Sa 
     //Destination * Source_Alpha 
     self.tempDrawImage.image?.draw(in: CGRect(x:0, y:0, width:self.view.frame.size.width, height:self.view.frame.size.height), blendMode: .destinationIn, alpha: 1.0) 
     //Let's apply this mask to the current drawing using XOR blending which removes any drawing underneath our mask but leaves everything else alone 
     self.mainImage.image?.draw(in: CGRect(x:0, y:0, width:self.view.frame.size.width, height:self.view.frame.size.height), blendMode: .xor, alpha: 1.0) 
    } 
    //let's apply the changes we've made to our mainImage 
    self.mainImage.image = UIGraphicsGetImageFromCurrentImageContext(); 
    self.tempDrawImage.image = nil; 

爲了瞭解它是如何運作的,你可以註釋掉抽獎單獨調用來看看他們是如何看一個更好的主意。

您可能會發現一些別名問題,您可能在筆畫邊緣留下少許位。要刪除在上下文alisasing的擦除模式打開圖紙時:

let ctx = UIGraphicsGetCurrentContext() 
    ctx?.setShouldAntialias(false) 
相關問題