2012-08-14 11 views
5

फ़ोटोशॉप जैसी निम्न ब्रश चिकनीता (कठोरता) प्रभाव कैसे प्राप्त करें? आईओएस ब्रश कठोरता फ़ोटोशॉप

मेरे प्रयास:

CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextSaveGState(context); 
CGContextSetLineCap(context, kCGLineCapRound); 
CGContextSetLineWidth(context, 30); 
CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:0.5f].CGColor); 
CGContextSetShadowWithColor(context, CGSizeMake(0, 0), 20.0f, [UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0f].CGColor); 
CGContextAddPath(context, path); 
CGContextStrokePath(context); 
CGContextRestoreGState(context); 

मैं अल्फा मूल्यों का समायोजन करने की कोशिश की, और छाया कलंक कारक है, लेकिन कोई सफल परिणाम।

क्या किसी के पास इसका समाधान है? किसी भी सहायता की सराहना की जाएगी।

उत्तर

11

इस छवि पर आप निम्नलिखित कोड परिणाम देख सकते हैं। मेरा मानना ​​है कि यह वही है जो आप चाहते हैं।

enter image description here

बस बाहरी छाया सिर्फ इतना है कि चिकनी प्रभाव है यही कारण है कि मैं सफेद रंग के साथ आकार देने के लिए कुछ भीतरी छाया जोड़ने देने के लिए पर्याप्त नहीं है।

- (void)drawRect:(CGRect)rect { 

    CGContextRef context = UIGraphicsGetCurrentContext(); 

    // Shadows 
    UIColor* shadow = UIColor.redColor; 
    CGSize shadowOffset = CGSizeMake(0.1, -0.1); 
    CGFloat shadowBlurRadius = 11; 
    UIColor* shadow2 = UIColor.whiteColor; // Here you can adjust softness of inner shadow. 
    CGSize shadow2Offset = CGSizeMake(0.1, -0.1); 
    CGFloat shadow2BlurRadius = 9; 

    // Rectangle Drawing 
    UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(59, 58, 439, 52) cornerRadius: 21]; 
    CGContextSaveGState(context); 
    CGContextSetShadowWithColor(context, shadowOffset, shadowBlurRadius, [shadow CGColor]); 
    [UIColor.redColor setFill]; 
    [rectanglePath fill]; 

    // Rectangle Inner Shadow 
    CGContextSaveGState(context); 
    UIRectClip(rectanglePath.bounds); 
    CGContextSetShadowWithColor(context, CGSizeZero, 0, NULL); 

    CGContextSetAlpha(context, CGColorGetAlpha([shadow2 CGColor])); 
    CGContextBeginTransparencyLayer(context, NULL); 
    { 
     UIColor* opaqueShadow = [shadow2 colorWithAlphaComponent: 1]; 
     CGContextSetShadowWithColor(context, shadow2Offset, shadow2BlurRadius, [opaqueShadow CGColor]); 
     CGContextSetBlendMode(context, kCGBlendModeSourceOut); 
     CGContextBeginTransparencyLayer(context, NULL); 

     [opaqueShadow setFill]; 
     [rectanglePath fill]; 

     CGContextEndTransparencyLayer(context); 
    } 
    CGContextEndTransparencyLayer(context); 
    CGContextRestoreGState(context); 

    CGContextRestoreGState(context); 
} 

आकार के आकार के बारे में आपको आंतरिक और बाहरी छाया दोनों धुंध त्रिज्या को समायोजित करना है।

+0

ऐसा लगता है कि आप एक आयत का उपयोग कर रहे हैं? आप स्ट्रोक के साथ ऐसा कैसे करेंगे? – ninjaneer

+0

@ निंजा हाँ यह आयताकार है, क्या आप 'स्पर्श' में ड्रॉ लाइन चाहते हैं और इसी तरह से प्रभावित होते हैं? – mohacs

+0

मुझे यकीन नहीं है कि यह प्रदर्शन को कैसे प्रभावित करेगा, लेकिन यदि यह स्ट्रोक पथ पर प्रभाव प्राप्त करता है, तो यह ठीक होगा। पिछले 12 घंटों में – ninjaneer

1

यह शायद सही जवाब नहीं है, लेकिन यह मेरी आवश्यकताओं के लिए सबसे अच्छा है।

ले लो FXBlurView: https://github.com/nicklockwood/FXBlurView

आप एक FXBlurView पर अपने स्ट्रोक आकर्षित या UIImage करने के लिए अपने UIView परिवर्तित करने के बाद आप ड्राइंग पूरा कर लें (कोड मैं इस सवाल का जवाब https://stackoverflow.com/a/22494886/505259 से ले लिया का प्रयोग करके) या तो कर सकते हैं:

+ (UIImage *) imageWithView:(UIView *)view 
{ 
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0f); 
    [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO]; 
    UIImage * snapshotImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return snapshotImage; 
} 

और UIImage पर FXBlurView की श्रेणी का उपयोग करें:

- (UIImage *)blurredImageWithRadius:(CGFloat)radius 
         iterations:(NSUInteger)iterations 
          tintColor:(UIColor *)tintColor; 

जिसके परिणामस्वरूप छवि को धुंधला करने के लिए, यह दे रही है एक फ़ोटोशॉप मुलायम ब्रश उपस्थिति की तरह।

हालांकि मैं अभी भी एक असली जवाब की तलाश में हूं। मेरे पास एक ओपनसीवी प्रोजेक्ट है जिसके लिए फ़ोटोशॉप के सॉफ्ट ब्रश टूल की सटीक प्रतिकृति की आवश्यकता है।

0

मैं आंतरिक चमक के साथ पथ खींचने पर काम कर रहा हूं, और किसी भी तरह से सफल हुआ (कम से कम मेरे स्वाद के लिए)।

मैंने levinunnick's Smooth-Line-View के शीर्ष पर ड्राइंग कोड लागू किया है। कोड एमआईटी लाइसेंस प्राप्त है, इसलिए आपको इसे अपनी परियोजना में जोड़ना होगा।

वर्तमान में आप जिस लाइन को आकर्षित करना चाहते हैं उसके लिए रेखा रंग, चौड़ाई और चिकनीता असाइन कर सकते हैं। चिकनीता से सावधान रहें, 0 - 1 के बीच एक फ्लोट का उपयोग करें। मैंने टच विधियों को बदल दिया है क्योंकि मुझे किसी अन्य दृश्य से ड्राइंग विधियों तक पहुंचने की आवश्यकता है। यदि आप टच विधियों पर वापस जाना चाहते हैं तो मूल कोड देखें।

यदि आपके पास कोई बेहतर विचार है, तो मैंने कोड को अनुकूलित नहीं किया है, बस इस उत्तर को संपादित करें।

@interface LineView : UIView 
- (instancetype)initWithFrame:(CGRect)frame andColor:(UIColor *)lineColor andWidth:(CGFloat)lineWidth andSmoothness:(CGFloat)lineSmooth;  
- (void)touchStartedWith:(CGPoint)location;  
- (void)touchMovedWith:(CGPoint)location; 
@end 

यह एम फ़ाइल है::

यहाँ एच फ़ाइल है

#import "LineView.h" 

static const CGFloat kPointMinDistance = 0.05f; 
static const CGFloat kPointMinDistanceSquared = kPointMinDistance * kPointMinDistance; 

@interface LineView() 
@property (strong) UIColor *lineColor; 
@property (assign) CGFloat lineWidth; 
@property (assign) CGFloat lineSmooth; 

@property (assign) CGPoint currentPoint; 
@property (assign) CGPoint previousPoint; 
@property (assign) CGPoint previousPreviousPoint; 
@end 

@implementation LineView 
{ 
@private 
    CGMutablePathRef _path; 
} 

- (instancetype)initWithFrame:(CGRect)frame andColor:(UIColor *)lineColor andWidth:(CGFloat)lineWidth andSmoothness:(CGFloat)lineSmooth 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
    _path = CGPathCreateMutable(); 

    if (lineSmooth < 0) lineSmooth = 0; 
    if (lineSmooth > 1) lineSmooth = 1; 

    self.backgroundColor = [UIColor clearColor]; 
    self.lineColor = lineColor; 
    self.lineWidth = lineWidth; 
    self.lineSmooth = lineWidth * (lineSmooth/4); 
    self.opaque = NO; 
    } 
    return self; 
} 

- (void)drawRect:(CGRect)rect 
{ 
    [self.backgroundColor set]; 
    UIRectFill(rect); 

    @autoreleasepool { 

    CGColorRef theColor = self.lineColor.CGColor; 
    UIColor *theClearOpaque = [[UIColor whiteColor] colorWithAlphaComponent:1]; 

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextAddPath(context, _path); 
    CGContextSetLineCap(context, kCGLineCapRound); 
    CGContextSetLineWidth(context, self.lineWidth); 
    CGContextSetStrokeColorWithColor(context, theColor); 

    // Outer shadow 
    CGSize shadowOffset = CGSizeMake(0.1f, -0.1f); 
    CGFloat shadowBlurRadius = self.lineSmooth; 
    CGContextSetShadowWithColor(context, shadowOffset, shadowBlurRadius, theColor); 

    CGContextStrokePath(context); 

    if (self.lineSmooth > 0) { 
     // Inner shadow 
     CGRect bounds = CGPathGetBoundingBox(_path); 
     CGRect drawBox = CGRectInset(bounds, -2.0f * self.lineWidth, -2.0f * self.lineWidth); 

     CGContextSaveGState(context); 
     UIRectClip(drawBox); 
     CGContextSetShadowWithColor(context, CGSizeZero, 0, NULL); 

     CGContextSetAlpha(context, CGColorGetAlpha(theClearOpaque.CGColor)); 
     CGContextBeginTransparencyLayer(context, NULL); 
     { 
     // Outer shadow 
     UIColor *oShadow = [theClearOpaque colorWithAlphaComponent:1]; 
     CGContextSetShadowWithColor(context, CGSizeMake(0.1f, -0.1f), self.lineWidth/64 * self.lineSmooth, oShadow.CGColor); 
     CGContextSetBlendMode(context, kCGBlendModeSourceOut); 
     CGContextBeginTransparencyLayer(context, NULL); 

     [oShadow setFill]; 

     // Draw the line again 
     CGContextAddPath(context, _path); 
     CGContextSetLineCap(context, kCGLineCapRound); 
     CGContextSetLineWidth(context, self.lineWidth); 
     CGContextSetStrokeColorWithColor(context, oShadow.CGColor); 
     CGContextStrokePath(context); 

     CGContextEndTransparencyLayer(context); 
     } 
     CGContextEndTransparencyLayer(context); 
     CGContextRestoreGState(context); 
    } 
    } 
} 

- (void)touchStartedWith:(CGPoint)location 
{ 
    self.previousPoint = location; 
    self.previousPreviousPoint = location; 
    self.currentPoint = location; 

    [self touchMovedWith:location]; 
} 

- (void)touchMovedWith:(CGPoint)location 
{ 
    CGRect drawBox; 

    @autoreleasepool { 
    CGFloat dx = location.x - self.currentPoint.x; 
    CGFloat dy = location.y - self.currentPoint.y; 

    if ((dx * dx + dy * dy) < kPointMinDistanceSquared) { 
     return; 
    } 

    self.previousPreviousPoint = self.previousPoint; 
    self.previousPoint = self.currentPoint; 
    self.currentPoint = location; 

    CGPoint mid1 = midPoint(self.previousPoint, self.previousPreviousPoint); 
    CGPoint mid2 = midPoint(self.currentPoint, self.previousPoint); 

    CGMutablePathRef subpath = CGPathCreateMutable(); 
    CGPathMoveToPoint(subpath, NULL, mid1.x, mid1.y); 
    CGPathAddQuadCurveToPoint(subpath, NULL, self.previousPoint.x, self.previousPoint.y, mid2.x, mid2.y); 

    CGRect bounds = CGPathGetBoundingBox(subpath); 
    drawBox = CGRectInset(bounds, -2.0f * self.lineWidth, -2.0f * self.lineWidth); 

    CGPathAddPath(_path, NULL, subpath); 
    CGPathRelease(subpath); 
    } 

    [self setNeedsDisplayInRect:drawBox]; 
} 

- (void)dealloc 
{ 
    CGPathRelease(_path); 
    _path = NULL; 
} 
@end 
3

आप जो के साथ अपने छाया सम्मिश्रण द्वारा प्राप्त करने के लिए कोशिश कर रहे हैं करने के लिए एक प्रभाव समान प्राप्त कर सकते हैं अपने स्ट्रोक

CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextAddPath(context, path); 
CGContextSetLineCap(context, kCGLineCapRound); 
CGContextSetLineWidth(context, self.lineWidth); 
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor); 
CGContextSetShadowWithColor(context, CGSizeMake(0.f, 0.f), self.lineWidth/4, [self.lineColor CGColor]); 
CGContextSetBlendMode(context, kCGBlendModeMultiply); 
CGContextSetAlpha(context, self.lineAlpha); 
CGContextStrokePath(context); 

मल्टीप्ली ब्लेंडिंग मोड के साथ, सफेद रंग को स्ट्रोक रंग के रूप में उपयोग करके और ब्रश का रंग सेट करने के साथ छाया के लिए चाहते हैं, तो आप निम्नलिखित परिणाम प्राप्त:

enter image description here

मैं touchesMoved घटना के लिए ड्राइंग समारोह कनेक्ट करते हैं, तो यह है कि जिस तरह से लंबे समय तक मैं छवि का एक हिस्सा पेंट करने के लिए, कठिन ले " ब्रश "खींचता है (काला रेखा देखें)।

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