SwiftGD

这是一个用于 libgd 的简单 Swift 封装,允许在服务器端 Swift 上进行基本的图形渲染,而服务器端 Swift 通常无法使用 Core Graphics。 虽然这个包最初是为了配合我的书《Server-Side Swift》而编写的,但对于任何希望在其服务器上执行图像操作的人来说,它也可能具有普遍用途。

SwiftGD 将 GD 封装在类中,使其更易于使用,并提供以下功能:

SwiftGD 为您管理 GD 资源,因此当您的图像被销毁时,底层内存会被释放。

安装

在您的计算机上安装 GD 库。如果您使用的是 macOS,请安装 Homebrew,然后运行命令 brew install gd。如果您使用的是 Linux,请以 root 身份运行 apt-get libgd-dev

修改您的 Package.swift 文件以包含以下依赖项

.package(url: "https://github.com/twostraws/SwiftGD.git", from: "2.0.0")

您还应该在您的目标依赖项列表中包含 “SwiftGD”。

SwiftGD 本身只有一个 Swift 依赖项,即 Cgd

SwiftGD 提供了四个类用于基本图像操作

这些被实现为类而不是结构体,因为只有类具有析构器。这些是必需的,以便在图像被销毁时可以清理 GD 的内存。

读取和写入图像

您可以像这样从磁盘加载图像

let location = URL(fileURLWithPath: "/path/to/image.png")
let image = Image(url: location)

这将返回一个可选的 Image 对象,如果加载因某种原因失败,则该对象将为 nil。SwiftGD 使用文件扩展名来加载正确的文件格式,因此请务必使用 “jpg”、“jpeg” 或 “png” 命名您的文件。

您还可以通过提供宽度和高度从头开始创建新图像,如下所示

let image = Image(width: 500, height: 500)

同样,如果内存分配正确,这将返回一个可选的 Image

您甚至可以从 Data 实例创建图像

let data: Data = ... // e.g. from networking request
let image = try Image(data: data, as: .png)

如果 data 实际上不是图像数据表示形式或与给定的栅格格式(在本例中为 .png)不匹配,这将抛出一个 Error。如果您省略栅格格式,将评估所有支持的栅格格式,如果任何格式匹配,将返回一个 Image(注意,这可能需要更长的时间)。

当您想将图像保存回磁盘时,请使用 Image 上的 write(to:) 方法,如下所示

let url = URL(fileURLWithPath: "/path/to/save.jpg")
image.write(to: url)

同样,格式由您选择的文件扩展名决定。如果文件已存在,write(to:) 将返回 false 并拒绝继续;如果文件保存成功,它将返回 true。

您还可以将图像导出为具有特定图像栅格格式的 Data 表示形式,如下所示

let image = Image(width: 500, height: 500)
image?.fill(from: .zero, color: .red)
let data = try image?.export(as: .png)

这将返回一个 500x500px 大小的红色 PNG 图像的数据表示形式。

当执行调整大小或裁剪操作时也会创建图像,这意味着您的原始图像不会被触及。 您有三种调整大小的选项:

所有这三个方法都有一个可选的额外参数 applySmoothing。当设置为 true(默认值)时,调整大小使用双线性滤波器执行。当为 false 时,调整大小使用最近邻插值执行,结果可能看起来有锯齿。

要裁剪图像,请调用其 cropped(to:) 方法,传入指定裁剪原点和大小的 Rectangle

绘制形状、颜色和图像

您可以使用九种方法在图像中进行绘制

操作图像

有几种方法可以将滤镜应用于图像对象

示例代码

第一个示例创建一个新的 500x500 图像,填充红色,在中心绘制一个蓝色椭圆,在顶部绘制一个绿色矩形,运行去饱和和着色滤镜,并将结果图像保存为 “output-1.png”

import Foundation
import SwiftGD

// figure out where to save our file
let currentDirectory = URL(fileURLWithPath: FileManager().currentDirectoryPath)
let destination = currentDirectory.appendingPathComponent("output-1.png")

// attempt to create a new 500x500 image
if let image = Image(width: 500, height: 500) {
    // flood from from X:250 Y:250 using red
    image.fill(from: Point(x: 250, y: 250), color: Color.red)

    // draw a filled blue ellipse in the center
    image.fillEllipse(center: Point(x: 250, y: 250), size: Size(width: 150, height: 150), color: Color.blue)
        
    // draw a filled green rectangle also in the center
    image.fillRectangle(topLeft: Point(x: 200, y: 200), bottomRight: Point(x: 300, y: 300), color: Color.green)

    // remove all the colors from the image
    image.desaturate()
        
    // now apply a dark red tint
    image.colorize(using: Color(red: 0.3, green: 0, blue: 0, alpha: 1))
        
    // save the final image to disk
    image.write(to: destination)
}

第二个示例绘制交替蓝白色的同心矩形,然后对结果应用高斯模糊

import Foundation
import SwiftGD

let currentDirectory = URL(fileURLWithPath: FileManager().currentDirectoryPath)
let destination = currentDirectory.appendingPathComponent("output-2.png")

if let image = Image(width: 500, height: 500) {
    var counter = 0
        
    for i in stride(from: 0, to: 250, by: 10) {
        let drawColor: Color
        
        if counter % 2 == 0 {
            drawColor = .blue
        } else {
            drawColor = .white
        }
        
        image.fillRectangle(topLeft: Point(x: i, y: i), bottomRight: Point(x: 500 - i, y: 500 - i), color: drawColor)
        counter += 1
    }

    image.blur(radius: 10)
    image.write(to: destination)
}

第三个示例通过在嵌套循环中设置单个像素来创建黑色、红色、绿色和黄色渐变

import Foundation
import SwiftGD

let currentDirectory = URL(fileURLWithPath: FileManager().currentDirectoryPath)
let destination = currentDirectory.appendingPathComponent("output-3.png")

let size = 500

if let image = Image(width: size, height: size) {
    for x in 0 ... size {
        for y in 0 ... size {
            image.set(pixel: Point(x: x, y: y), to: Color(red: Double(x) / Double(size), green: Double(y) / Double(size), blue: 0, alpha: 1))
        }
    }
        
    image.write(to: destination)
}

许可证

本软件包根据 MIT 许可证发布,许可证内容如下。

版权所有 (c) 2017 Paul Hudson

特此授予任何人免费获得本软件及相关文档文件(“软件”)副本的许可,以便在不受限制的情况下处理本软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售本软件副本的权利,并允许向接受本软件的人员提供本软件,但须符合以下条件

上述版权声明和本许可声明应包含在本软件的所有副本或主要部分中。

本软件按“原样”提供,不提供任何形式的明示或暗示保证,包括但不限于适销性、特定用途适用性和非侵权保证。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权诉讼或其他诉讼中,因本软件或本软件的使用或其他交易而产生、产生或与之相关的任何索赔、损害或其他责任。