UIImage
でUIBezierPath
を作成するコードをいくつか作成しましたが、機能しませんでした。
誰かが私のコードの何が問題なのかを見つけるのを手伝ってもらえますか?
-(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;
}
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
}
}
ベジェでの最初のビュー
2番目-画像に変換されたベジェ
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
}
}