如何使用UIBezierPath创建UIImage
我写了一些代码用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: 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 } }
演示应用程序
参考
尝试这个
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的第一个视图
第二 – 贝塞尔变换为图像