How to create a UIImage with UIBezierPath

前端 未结 7 856
南旧
南旧 2020-12-09 06:02

I wrote some code to create a UIImage with UIBezierPath but it didn\'t work.

Can someone help me find out what\'s wrong with my code?

相关标签:
7条回答
  • 2020-12-09 06:14

    https://stackoverflow.com/a/17408397/3191351 Translated Into Swift

    import UIKit
    
    extension UIBezierPath {
    
        /** Returns an image of the path drawn using a stroke */
        func strokeImageWithColor(var strokeColor: UIColor?,var fillColor: UIColor?) -> UIImage {
    
            // get your bounds
            let bounds: CGRect = self.bounds
    
            UIGraphicsBeginImageContextWithOptions(CGSizeMake(bounds.size.width + self.lineWidth * 2, bounds.size.width + self.lineWidth * 2), false, UIScreen.mainScreen().scale)
    
            // get reference to the graphics context
            let reference: CGContextRef = UIGraphicsGetCurrentContext()!
    
            // translate matrix so that path will be centered in bounds
            CGContextTranslateCTM(reference, self.lineWidth, self.lineWidth)
    
            if strokeColor == nil {
                strokeColor = fillColor!;
            }
            else if fillColor == nil {
                fillColor = strokeColor!;
            }
    
            // set the color
            fillColor?.setFill()
            strokeColor?.setStroke()
    
            // draw the path
            fill()
            stroke()
    
    
            // grab an image of the context
            let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
    
            UIGraphicsEndImageContext()
    
            return image
        }
    
    }
    
    0 讨论(0)
  • 2020-12-09 06:14
    extension UIBezierPath {
        func shapeImage(view: UIView) -> UIImage! {
    
        // begin graphics context for drawing
        UIGraphicsBeginImageContextWithOptions(view.frame.size, false, UIScreen.main.scale)
    
        // configure the view to render in the graphics context
        //view.layer.render(in: UIGraphicsGetCurrentContext()!)
    
        // get reference to the graphics context
        let context = UIGraphicsGetCurrentContext()
    
        // translate matrix so that path will be centered in bounds
        context?.translateBy(x: -(bounds.origin.x - self.lineWidth), y: -(bounds.origin.y - self.lineWidth))
        // set color
        UIColor.black.setStroke()
    
        // draw the stroke
        stroke()
    
        // get an image of the graphics context
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    
        // end the context
        UIGraphicsEndImageContext()
    
        return image
        }
    }
    

    first view with Bezier

    second - bezier transformed to image

    0 讨论(0)
  • 2020-12-09 06:15

    try this category to UIBezierPath

    @interface UIBezierPath (Image)
    
    /** Returns an image of the path drawn using a stroke */
    -(UIImage*) strokeImageWithColor:(UIColor*)color;
    
    @end
    
    @implementation UIBezierPath (Image)
    
    -(UIImage*) strokeImageWithColor:(UIColor*)color {
        // adjust bounds to account for extra space needed for lineWidth
        CGFloat width = self.bounds.size.width + self.lineWidth * 2;
        CGFloat height = self.bounds.size.height + self.lineWidth * 2;
        CGRect bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, width, height);
    
        // create a view to draw the path in
        UIView *view = [[UIView alloc] initWithFrame:bounds];
    
        // begin graphics context for drawing
        UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, [[UIScreen mainScreen] scale]);
    
        // configure the view to render in the graphics context
        [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    
        // get reference to the graphics context
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        // translate matrix so that path will be centered in bounds
        CGContextTranslateCTM(context, -(bounds.origin.x - self.lineWidth), -(bounds.origin.y - self.lineWidth));
    
        // set color
        [color set];
    
        // draw the stroke
        [self stroke];
    
        // get an image of the graphics context
        UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    
        // end the context
        UIGraphicsEndImageContext();
    
        return viewImage;
    }
    
    @end
    
    0 讨论(0)
  • 2020-12-09 06:23

    Your usage would be:

    UIBezierPath *path = [UIBezierPath trianglePathWithSize: CGSizeMake(50, 50)];
                  path.lineWidth = 2;
    
    UIImage *image = [path imageWithStrokeColor: [UIColor blueColor] 
                                      fillColor: [UIColor redColor]];
    

    Category to create bezier path shapes:

    @implementation UIBezierPath (Shapes)
    
    + (UIBezierPath *) trianglePathWithSize: (CGSize) size;
    {
        UIBezierPath *result = [UIBezierPath bezierPath];
        result.lineJoinStyle = kCGLineJoinMiter;
    
        [result moveToPoint: CGPointMake(0, 0)];
        [result addLineToPoint: CGPointMake(size.width, size.height / 2)];
        [result addLineToPoint: CGPointMake(0, size.height)];
        [result closePath];
    
        return result;
    }
    
    @end
    

    Category to take any path and render in UIImage from it:

    @implementation UIBezierPath (UIImage)
    
    - (UIImage *) imageWithStrokeColor: (UIColor *) strokeColor fillColor: (UIColor *) 
    
    fillColor;
    {
        CGRect bounds = self.bounds;
    
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(bounds.size.width + self.lineWidth * 2, bounds.size.width + self.lineWidth * 2),
                                               false, [UIScreen mainScreen].scale);
    
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        // offset the draw to allow the line thickness to not get clipped
        CGContextTranslateCTM(context, self.lineWidth, self.lineWidth);
    
        if (!strokeColor)
        {
            strokeColor = fillColor;
        }
        else
        if (!fillColor)
        {
            fillColor = strokeColor;
        }
    
        [strokeColor setStroke];
        [fillColor setFill];
    
        [self fill];
        [self stroke];
    
        UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    
        UIGraphicsEndImageContext();
    
        return result;
    }
    
    @end
    
    0 讨论(0)
  • 2020-12-09 06:25

    Try This

    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    
    maskLayer.frame = imageview.frame;
    
    maskLayer.path = [path CGPath];
    
    imageview.layer.mask = maskLayer;
    
    0 讨论(0)
  • 2020-12-09 06:26

    You can create image with BeizerPath Swift-3 :-

    import UIKit
    
    class ViewController: UIViewController {
        @IBOutlet weak var imageOutlet: UIImageView!
        override func viewDidLoad() {
            super.viewDidLoad()
            let path3 = createBeizePath()
            let image:UIImage = UIImage.shapeImageWithBezierPath(bezierPath: path3, fillColor: .red, strokeColor: .black)
            imageOutlet.image = image
    }
    
    func createBeizePath() -> UIBezierPath
    {
        let path = UIBezierPath()
        //Rectangle path Trace
        path.move(to: CGPoint(x: 20, y: 100) )
        path.addLine(to: CGPoint(x: 50 , y: 100))
        path.addLine(to: CGPoint(x: 50, y: 150))
        path.addLine(to: CGPoint(x: 20, y: 150))
        return path
      }
    

    }

    extension UIImage {
    
        class func shapeImageWithBezierPath(bezierPath: UIBezierPath, fillColor: UIColor?, strokeColor: UIColor?, strokeWidth: CGFloat = 0.0) -> UIImage! {
            bezierPath.apply(CGAffineTransform(translationX: -bezierPath.bounds.origin.x, y: -bezierPath.bounds.origin.y ) )
            let size = CGSize(width: 100    , height: 100)
            UIGraphicsBeginImageContext(size)
            let context = UIGraphicsGetCurrentContext()
            var image = UIImage()
            if let context  = context {
                context.saveGState()
                context.addPath(bezierPath.cgPath)
                if strokeColor != nil {
                    strokeColor!.setStroke()
                    context.setLineWidth(strokeWidth)
                } else { UIColor.clear.setStroke() }
                fillColor?.setFill()
                context.drawPath(using: .fillStroke)
                 image = UIGraphicsGetImageFromCurrentImageContext()!
                context.restoreGState()
                UIGraphicsEndImageContext()
            }
            return image
        }
    
    }
    

    Demo App

    Reference

    0 讨论(0)
提交回复
热议问题