繁体   English   中英

如何使用 UIBezierPath 创建 UIImage

[英]How to create a UIImage with UIBezierPath

我写了一些代码来使用UIBezierPath创建一个UIImage但它没有用。

有人可以帮我找出我的代码有什么问题吗?

-(UIImage*) drawTriangle{
    CGRect rect = CGRectMake(0.0, 0.0, 30.0, 30.0);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    UIGraphicsPushContext(context);
    UIBezierPath *bezier = [UIBezierPath bezierPathWithRect:rect];
    [bezier moveToPoint:CGPointMake(25, 5)];
    [bezier addLineToPoint:CGPointMake(5, 15)];
    [bezier addLineToPoint:CGPointMake(25, 25)];
    [bezier setLineWidth:3.0];
    [bezier setLineJoinStyle:kCGLineJoinBevel];
    [bezier stroke];
    CGContextAddPath(context, bezier.CGPath);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsPopContext();
    UIGraphicsEndImageContext();
    return image;
}

试试这个类别到 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

您的用法是:

UIBezierPath *path = [UIBezierPath trianglePathWithSize: CGSizeMake(50, 50)];
              path.lineWidth = 2;

UIImage *image = [path imageWithStrokeColor: [UIColor blueColor] 
                                  fillColor: [UIColor redColor]];

创建贝塞尔曲线路径形状的类别:

@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

使用任何路径并从中渲染 UIImage 的类别:

@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

您可以使用 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: bezierPath.bounds.width, height: bezierPath.bounds.height)
        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
    }

}

在此处输入图片说明

演示应用

参考

试试这个

CAShapeLayer *maskLayer = [CAShapeLayer layer];

maskLayer.frame = imageview.frame;

maskLayer.path = [path CGPath];

imageview.layer.mask = maskLayer;

我发现我的代码有什么问题。

我在代码顺序上犯了一个错误。 只需将UIGraphicsBeginImageContext(rect.size)移动到适当的位置。

-(UIImage*) drawTriangle{
    CGRect rect = CGRectMake(0.0, 0.0, 30.0, 30.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    UIGraphicsPushContext(context);
    UIGraphicsBeginImageContext(rect.size); //now it's here.
    UIBezierPath *bezier = [UIBezierPath bezierPathWithRect:rect];
    [bezier moveToPoint:CGPointMake(25, 5)];
    [bezier addLineToPoint:CGPointMake(5, 15)];
    [bezier addLineToPoint:CGPointMake(25, 25)];
    [bezier setLineWidth:3.0];
    [bezier setLineJoinStyle:kCGLineJoinBevel];
    [bezier stroke];
    CGContextAddPath(context, bezier.CGPath);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsPopContext();
    UIGraphicsEndImageContext();
    return image;
}

https://stackoverflow.com/a/17408397/3191351翻译成 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
    }

}
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
    }
}

Bezier 的第一个视图

第二个 - 贝塞尔转换为图像

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM