2012-04-05 12 views
6

का उपयोग करके स्पर्श के साथ UIImageVIew में एक छवि मिटाएं और मिटाएं। मेरा प्रश्न here पर उल्लिखित जैसा है। मैं अपने ऐप में दो छवियों का भी उपयोग कर रहा हूं और मुझे बस स्पर्श करके शीर्ष छवि को मिटाना है। फिर स्पर्श करके मिटाए गए भाग को मिटाएं (यदि आवश्यक हो)। मैं शीर्ष छवि को मिटाने के लिए निम्न कोड का उपयोग कर रहा हूं। इस दृष्टिकोण में भी एक समस्या है। यह है कि छवियां बड़ी हैं और मैं उन्हें उचित रूप से प्रदर्शित करने के लिए पहलू फ़िट सामग्री मोड का उपयोग कर रहा हूं। जब मैं स्क्रीन पर स्पर्श करता हूं, तो यह कोने में छुआ जगह पर मिटा देता है। मुझे लगता है कि टच पॉइंट गणना के लिए कुछ फिक्स की आवश्यकता है। किसी भी तरह की सहायता को आभार समझेंगे।कोरिग्राफिक्स

दूसरी समस्या यह है कि मिटाए गए हिस्से को स्पर्श करके कैसे मिटाया जाए?

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

+0

कृपया उत्तर दें कि क्या आपके पास इसका समाधान है। – Muzammil

उत्तर

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, ग्रेस्केल, 8 बीपीपी, नो अल्फा बनाता है। इस संदर्भ का उपयोग मास्क को स्टोर करने के लिए किया जाता है, जिसे अग्रभूमि छवि पर लागू किया जाएगा।

  • हर बार जब आप स्क्रीन पर उंगली लेते हैं, तो CGBitmapContextRef पर कोरग्राफिक्स का उपयोग करके एक रेखा खींची जाती है, छवि को प्रकट करने के लिए सफेद, इसे छिपाने के लिए काला। इस तरह हम एक बी/डब्ल्यू ड्राइंग संग्रहित कर रहे हैं।

  • drawRect: नियमित बस ड्रॉ पृष्ठभूमि, तो CGBitmapContextRef से एक CGImageRef बनाता है और एक मुखौटा के रूप में वर्तमान संदर्भ के लिए यह लागू होता है। फिर अग्रभूमि छवि खींचती है। छवियों को आकर्षित करने के लिए यह - (void)drawImageScaled:(UIImage *)image का उपयोग करता है, जो सिर्फ छवि को स्केल और केंद्रित करता है।

  • यदि आप दृश्य का आकार बदलने की योजना बना रहे हैं, तो आपको - (void)setFrame:(CGRect)frame ओवरराइड करने के लिए नए आकार के साथ मुखौटा की प्रतिलिपि बनाने या फिर से बनाने के लिए एक विधि लागू करनी चाहिए।

  • - (void)reset विधि बस मुखौटा को साफ़ करती है।

  • बिटमैप संदर्भ नहीं किसी भी अल्फ़ा चैनल, ग्रेस्केल रंग इस्तेमाल किया स्थान है यहां तक ​​कि अगर अल्फा है: यही कारण है कि हर बार एक रंग सेट कर दिया जाता है, मैं दो घटकों को निर्दिष्ट करने के लिए किया था है।

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

+0

बहुत बहुत धन्यवाद यह अच्छी तरह से काम करता है। और यह वही है जो मुझे चाहिए था। – gigahari

+0

Unerase के बारे में क्या? मैं छवि को कैसे मिटा सकता हूं? –

+0

संपत्ति 'touchRevealsImage' के मान को बदलें। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^