2012-04-05 78 views
6

我的問題與here中提到的相同。我也在我的應用程序中使用兩個圖像,我需要的是通過觸摸來擦除頂部圖像。然後通過觸摸刪除(如果需要)刪除的部分。我正在使用以下代碼來擦除頂部圖像。這種方法也存在問題。這是圖像很大,我使用Aspect Fit內容模式來正確顯示它們。 當我觸摸屏幕時,它在角落而不是被觸摸的地方消失。我認爲觸摸點計算需要一些修復。任何幫助將不勝感激。使用coregraphics刪除和刪除UIImageVIew中的圖像

第二個問題是,如何通過觸摸來刪除擦除的部分?

UIGraphicsBeginImageContext(self.imgTop.image.size); 
[self.imgTop.image drawInRect:CGRectMake(0, 0, self.imgTop.image.size.width, self.imgTop.image.size.height)]; 
self.frame.size.width, self.frame.size.height)]; 
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); 
GContextSetLineWidth(UIGraphicsGetCurrentContext(), pinSize); 
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0, 0, 0, 1.0); 
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy); 

CGContextBeginPath(UIGraphicsGetCurrentContext()); 
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y); 
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y); 
CGContextStrokePath(UIGraphicsGetCurrentContext()); 
self.imgTop.contentMode = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
+0

你有沒有找到解決這個問題?如果你找到一個解決方案,你能分享一下解決方案嗎我面臨完全相同的問題,無法找到合適的解決方案。 – Anuj 2012-09-11 12:06:04

+0

如果您有解決方案,請回復。 – Muzammil 2012-11-02 12:14:13

回答

6

你的代碼是相當含糊:你創建上下文與imgTop裏面,然後用kCGBlendModeCopy黑混色?這會導致黑色被複制到imgTop。我假設你想設置圖層的content屬性呢?

無論如何,這個班級做你所需要的。只有一些有趣的方法(他們在頂部),其他只是屬性或init...例程。

@interface EraseImageView : UIView { 
    CGContextRef context; 
    CGRect contextBounds; 
} 

@property (nonatomic, retain) UIImage *backgroundImage; 
@property (nonatomic, retain) UIImage *foregroundImage; 
@property (nonatomic, assign) CGFloat touchWidth; 
@property (nonatomic, assign) BOOL touchRevealsImage; 

- (void)resetDrawing; 

@end 

@interface EraseImageView() 
- (void)createBitmapContext; 
- (void)drawImageScaled:(UIImage *)image; 
@end 

@implementation EraseImageView 
@synthesize touchRevealsImage=_touchRevealsImage, backgroundImage=_backgroundImage, foregroundImage=_foregroundImage, touchWidth=_touchWidth; 

#pragma mark - Main methods - 

- (void)createBitmapContext 
{ 
    // create a grayscale colorspace 
    CGColorSpaceRef grayscale=CGColorSpaceCreateDeviceGray(); 

    /* TO DO: instead of saving the bounds at the moment of creation, 
       override setFrame:, create a new context with the right 
       size, draw the previous on the new, and replace the old 
       one with the new one. 
    */ 
    contextBounds=self.bounds; 

    // create a new 8 bit grayscale bitmap with no alpha (the mask) 
    context=CGBitmapContextCreate(NULL, 
            (size_t)contextBounds.size.width, 
            (size_t)contextBounds.size.height, 
            8, 
            (size_t)contextBounds.size.width, 
            grayscale, 
            kCGImageAlphaNone); 

    // make it white (touchRevealsImage==NO) 
    CGFloat white[]={1., 1.}; 
    CGContextSetFillColor(context, white); 

    CGContextFillRect(context, contextBounds); 

    // setup drawing for that context 
    CGContextSetLineCap(context, kCGLineCapRound); 
    CGContextSetLineJoin(context, kCGLineJoinRound); 

    CGColorSpaceRelease(grayscale); 
} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *touch=(UITouch *)[touches anyObject]; 

    // the new line that will be drawn 
    CGPoint points[]={ 
     [touch previousLocationInView:self], 
     [touch locationInView:self] 
    }; 

    // setup width and color 
    CGContextSetLineWidth(context, self.touchWidth); 
    CGFloat color[]={(self.touchRevealsImage ? 1. : 0.), 1.}; 
    CGContextSetStrokeColor(context, color); 

    // stroke 
    CGContextStrokeLineSegments(context, points, 2); 

    [self setNeedsDisplay]; 

} 

- (void)drawRect:(CGRect)rect 
{ 
    if (self.foregroundImage==nil || self.backgroundImage==nil) return; 

    // draw background image 
    [self drawImageScaled:self.backgroundImage]; 

    // create an image mask from the context 
    CGImageRef mask=CGBitmapContextCreateImage(context); 

    // set the current clipping mask to the image 
    CGContextRef ctx=UIGraphicsGetCurrentContext(); 
    CGContextSaveGState(ctx); 

    CGContextClipToMask(ctx, contextBounds, mask); 

    // now draw image (with mask) 
    [self drawImageScaled:self.foregroundImage]; 

    CGContextRestoreGState(ctx); 

    CGImageRelease(mask); 

} 

- (void)resetDrawing 
{ 
    // draw black or white 
    CGFloat color[]={(self.touchRevealsImage ? 0. : 1.), 1.}; 

    CGContextSetFillColor(context, color); 
    CGContextFillRect(context, contextBounds); 

    [self setNeedsDisplay]; 
} 

#pragma mark - Helper methods - 

- (void)drawImageScaled:(UIImage *)image 
{ 
    // just draws the image scaled down and centered 

    CGFloat selfRatio=self.frame.size.width/self.frame.size.height; 
    CGFloat imgRatio=image.size.width/image.size.height; 

    CGRect rect={0.,0.,0.,0.}; 

    if (selfRatio>imgRatio) { 
     // view is wider than img 
     rect.size.height=self.frame.size.height; 
     rect.size.width=imgRatio*rect.size.height; 
    } else { 
     // img is wider than view 
     rect.size.width=self.frame.size.width; 
     rect.size.height=rect.size.width/imgRatio; 
    } 

    rect.origin.x=.5*(self.frame.size.width-rect.size.width); 
    rect.origin.y=.5*(self.frame.size.height-rect.size.height); 

    [image drawInRect:rect]; 
} 

#pragma mark - Initialization and properties - 

- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    if ((self=[super initWithCoder:aDecoder])) { 
     [self createBitmapContext]; 
     _touchWidth=10.; 
    } 
    return self; 
} 

- (id)initWithFrame:(CGRect)frame 
{ 
    if ((self=[super initWithFrame:frame])) { 
     [self createBitmapContext]; 
     _touchWidth=10.; 
    } 
    return self; 
} 

- (void)dealloc 
{ 
    CGContextRelease(context); 
    [super dealloc]; 
} 

- (void)setBackgroundImage:(UIImage *)value 
{ 
    if (value!=_backgroundImage) { 
     [_backgroundImage release]; 
     _backgroundImage=[value retain]; 
     [self setNeedsDisplay]; 
    } 
} 

- (void)setForegroundImage:(UIImage *)value 
{ 
    if (value!=_foregroundImage) { 
     [_foregroundImage release]; 
     _foregroundImage=[value retain]; 
     [self setNeedsDisplay]; 
    } 
} 

- (void)setTouchRevealsImage:(BOOL)value 
{ 
    if (value!=_touchRevealsImage) { 
     _touchRevealsImage=value; 
     [self setNeedsDisplay]; 
    } 
} 

@end 

一些注意事項:

  • 該類保留你所需要的兩個圖像。它有一個touchRevealsImage屬性將模式設置爲繪製或擦除,並且可以設置線條的寬度。

  • 初始化時,它創建一個CGBitmapContextRef,灰度,8bpp,沒有alpha,具有相同大小的視圖。此上下文用於存儲將應用於前景圖像的遮罩。

  • 每次在屏幕上移動手指時,使用CoreGraphics在CGBitmapContextRef上畫一條線,白色顯示圖像,黑色隱藏圖像。這樣我們就可以存儲黑白圖。

  • drawRect:例程簡單地繪製背景,然後從CGBitmapContextRef創建CGImageRef並將其作爲掩碼應用於當前上下文。然後繪製前景圖像。爲了繪製圖像,它使用- (void)drawImageScaled:(UIImage *)image,它只是繪製縮放和居中的圖像。

  • 如果您打算調整視圖的大小,應該實施一種方法來複制或重新創建具有新大小的蒙版,覆蓋- (void)setFrame:(CGRect)frame

  • - (void)reset方法只是清除掩碼。

  • 即使位圖背景下也沒有任何alpha通道,用於灰度色彩空間有阿爾法:這就是爲什麼每一個顏色設定的時間,我必須指定兩個組成部分。

Sample application with <code>EraseImageView</code> class

+0

非常感謝,它效果很好。而這正是我所需要的。 – gigahari 2012-12-27 10:49:25

+0

怎麼樣Unerase?我怎樣才能使圖像不會消失? – 2012-12-28 06:09:04

+0

更改「touchRevealsImage」屬性的值。 – 2013-01-03 13:00:00