使用Swift绘制UIBezierPath到UIImage并转换为Base64格式的图片无法正常工作

3

我创建了一些代码,用于在UIImage上下文中创建UIBezierPath。然后将图像转换为base64字符串。我认为我应该在UIImage的开头和结尾之间绘制路径。但是,经过多个小时的尝试,它并没有起作用。我正在将base64字符串复制到网站上下载图片以查看其是否有效。我是在playground中编写代码的:

import Foundation
import UIKit


UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), false, 0.0)
let image = UIGraphicsGetImageFromCurrentImageContext()

UIColor.blackColor().setStroke()
let path = UIBezierPath()
path.lineWidth = 2
path.moveToPoint(CGPointMake(100, 0))

path.addLineToPoint(CGPointMake(200, 40))
path.addLineToPoint(CGPointMake(160, 140))
path.addLineToPoint(CGPointMake(40, 140))
path.addLineToPoint(CGPointMake(0, 40))
path.closePath()

UIGraphicsEndImageContext();
let data = UIImagePNGRepresentation(image)
let b64 = data?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
print(b64!)

生成的PNG图片大小为1000x1000,我猜测是因为我的Retina显示屏。但图片本身是完全透明的,看不到任何内容。我正在使用这个网站解码base64并保存文件,我已经试过另外两个网站来确定是否是该网站的问题。 http://www.motobit.com/util/base64-decoder-encoder.asp 编辑: 我刚刚尝试了下面的代码,以确定问题是出在我的图片、Bezier或保存为bas64上。这段代码很好用,所以我认为这是我的Bezier出了问题。
import Foundation
import UIKit

let image = UIImage(data: NSData(contentsOfURL: NSURL(string: "http://i.imgur.com/crr4m48.jpg")!)!)!

let data = UIImagePNGRepresentation(image)
let b64 = data?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
print(b64!)

问题出在创建图像还是转换为Base64?这两个操作完全不相关。将PNG数据保存到文件中,看看是否可以打开该图像文件。如果可以,则问题出在您的Base64转换上。此外,加载一些现有的图像并使用它们作为输入到您的Base64代码 - 会发生什么? - Caleb
@Caleb 我刚刚尝试了从URL加载并且运行正常。问题可能出在我的UIBezierPath上。 - Johnston
3个回答

2

看起来你的操作顺序有误。例如:

UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), false, 0.0)
let image = UIGraphicsGetImageFromCurrentImageContext()

在绘制图形上下文之前,为什么要获取image?我认为你会得到一个空的图像--这不像你在上下文中绘制东西时得到的图像。等到你完成所有的绘画后再获取图像。另外,该函数的文档说明如下:

只有当基于位图的图形上下文是当前图形上下文时,您才应调用此函数。如果当前上下文为nil或未通过调用UIGraphicsBeginImageContext创建,则此函数返回nil。

所以,请确保您已满足该要求,并且在调用UIGraphicsBeginImageContext()时获得的图像不是nil
接下来,您正在创建一个贝塞尔路径:
let path = UIBezierPath()
path.lineWidth = 2
path.moveToPoint(CGPointMake(100, 0))
path.addLineToPoint(CGPointMake(200, 40))
//...

但是为了在你的上下文中实际绘制出这条路径,你必须做一些绘制的事情,比如调用path.fill()path.stroke()。我没有看到这个步骤,所以即使你解决了上面的第一个问题,你仍然会得到一个空图像,直到你进行一些绘制。


你是完全正确的,这个方法百分之百有效。在创建形状路径并调用path.stroke()后,我需要调用UIGraphicsGetImageFromCurrentImageContext()来使其运动起来。 - Johnston

0

你需要直接使用图像上下文进行操作。你可以尝试使用当前图像上下文创建CGContextRef,例如:

UIGraphicsBeginImageContext(CGSizeMake(200, 200))
var context: CGContextRef = UIGraphicsGetCurrentContext()

然后直接将您的路径添加到其中:

CGContextAddPath(context, path)

或者您可以使用上下文方法(例如CGContextAddCurveToPoint)创建曲线,然后使用以下代码绘制路径:

CGContextStrokePath(context)

最后一步是从中创建图像:

let image = UIGraphicsGetImageFromCurrentImageContext()

0

除了@Caleb外,还有一个要点:

如果您正在绘制 1000x1000 像素 的图像.png,则 UIGraphicsBeginImageContext 参数必须与上面的不同:-

    //Swift-3 Syntax
    UIGraphicsBeginImageContextWithOptions( CGSize(width:500, height:500 ), false , 2.0 )

enter image description here

参考资料


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接