2017-07-15 92 views
1

如何创建三角形UIImage?以下是我现在正在做的事情,但它根本没有生成任何图像。如何创建三角形UIImage

extension UIImage { 

    static func triangle(side: CGFloat, color: UIColor)->UIImage { 
     UIGraphicsBeginImageContextWithOptions(CGSize(width: side, height: side), false, 0) 
     let ctx = UIGraphicsGetCurrentContext()! 
     ctx.saveGState() 

     ctx.beginPath() 
     ctx.move(to: CGPoint(x: side/2, y: 0)) 
     ctx.move(to: CGPoint(x: side, y: side)) 
     ctx.move(to: CGPoint(x: 0, y: side)) 
     ctx.move(to: CGPoint(x: side/2, y: 0)) 
     ctx.closePath() 

     ctx.setFillColor(color.cgColor) 

     ctx.restoreGState() 
     let img = UIGraphicsGetImageFromCurrentImageContext()! 
     UIGraphicsEndImageContext() 

     return img 
    } 
} 

回答

2

您的路径不包含任何行,所以没有区域可以填充。另外你不是在绘制路径。

尝试是这样的:

static func triangle(side: CGFloat, color: UIColor)->UIImage { 
    UIGraphicsBeginImageContextWithOptions(CGSize(width: side, height: side), false, 0) 
    let ctx = UIGraphicsGetCurrentContext()! 
    ctx.saveGState() 

    ctx.beginPath() 
    ctx.move(to: CGPoint(x: side/2, y: 0)) 
    //### Add lines 
    ctx.addLine(to: CGPoint(x: side, y: side)) 
    ctx.addLine(to: CGPoint(x: 0, y: side)) 
    //ctx.addLine(to: CGPoint(x: side/2, y: 0)) //### path is automatically closed 
    ctx.closePath() 

    ctx.setFillColor(color.cgColor) 

    ctx.drawPath(using: .fill) //### draw the path 

    ctx.restoreGState() 
    let img = UIGraphicsGetImageFromCurrentImageContext()! 
    UIGraphicsEndImageContext() 

    return img 
} 
+0

但是,三角形的两个底点之间的界限呢? - 看起来并不像它那里添加的那样 – shoe

+0

@shoe - 这就是'closePath'所做的,完成回到你开始它的路径。 – Rob

+0

@Rob,但画了一条线回到我开始的地方,它不会关闭三角形。似乎缺少的是三角形的“基础”。这里是我如何解释代码 - 让我知道如果我错了 - 路径开始,我们移动到三角形的顶部,从那里添加一条线到三角形的正确点。然后,仍然在三角形的顶部,我们从顶部到左侧添加另一条线,然后关闭路径。它看起来像'closePath()'自动在三角形的两个底点之间添加一条线。这是怎么回事? – shoe

0

OOPer告诉你的是你缺乏线,并没有实际绘制的三角形。

除此之外,我建议避免使用图形上下文。 UIBezierPath使它更简洁,更容易绘制,而不必担心上下文。此外,您不需要保存和恢复上下文,因为您正在创建一个临时上下文,然后立即丢弃它。

下面是一个完整的操场,吸引你的三角形(和填充和中风的图像矩形,以便更容易看到 - 你会删除笔划和可能与UIColor.clear填充形状代替。)

import UIKit 
import PlaygroundSupport 

PlaygroundPage.current.needsIndefiniteExecution = true 


extension UIImage { 

    static func triangle(side: CGFloat, color: UIColor)->UIImage { 
    UIGraphicsBeginImageContextWithOptions(CGSize(width: side, height: side), false, 0) 

    //First fill the bounds with white 
    let rectPath = UIBezierPath(rect: CGRect(x:0, y: 0, width: side, height: side)) 
    UIColor.white.setFill() //Use clear if you want your image to only contain the triangle. 
    rectPath.fill() 

    //Now build the triangle path 
    let path = UIBezierPath() 
    path.move(to: CGPoint(x: side/2, y: 0)) 
    path.addLine(to: CGPoint(x: side, y: side)) 
    path.addLine(to: CGPoint(x: 0, y: side)) 
    path.close() //Closing the path draws the final line 
    color.setFill() 
    path.fill() 

    //Stroke the outer path in gray so you can see the bounds - remove if desired 
    UIColor.gray.setStroke() 
    rectPath.stroke() 

    let img = UIGraphicsGetImageFromCurrentImageContext()! 
    UIGraphicsEndImageContext() 

    return img 
    } 
} 

let imageView = UIImageView(frame: CGRect(x:0, y: 0, width: 200, height: 200)) 


PlaygroundPage.current.liveView = imageView 
imageView.image = UIImage.triangle(side: 200.0, color: UIColor.yellow) 
1

或者,你可以丢失核心图形代码,进一步简化它:

extension UIImage { 

    static func triangle(side: CGFloat, color: UIColor) -> UIImage { 
     UIGraphicsBeginImageContextWithOptions(CGSize(width: side, height: side), false, 0) 

     let path = UIBezierPath() 
     path.move(to: CGPoint(x: side/2, y: 0)) 
     path.addLine(to: CGPoint(x: side, y: side)) 
     path.addLine(to: CGPoint(x: 0, y: side)) 
     path.close() 

     color.setFill() 
     path.fill() 

     let image = UIGraphicsGetImageFromCurrentImageContext()! 
     UIGraphicsEndImageContext() 

     return image 
    } 
}