位图 (Bitmap)

tag Swift License MIT SPM

macOS iOS tvOS watchOS macCatalyst

一个方便的 Swift 工具,用于加载/保存和操作位图图像。

为什么需要它?

我需要一个简单的 Swift 接口来封装一些常见的图像操作,这些操作是我日常图像处理中经常遇到的,其中最主要的是能够轻松地直接绘制到位图图像中。

定义

Bitmap 对象表示一个 RGBA 图像。图像数据在内部存储在一个简单的 1 维字节数组中,表示像素的 R、G、B、A 序列。

位图对象持有并管理位图的 CGContext 表示,允许直接在位图上进行 CG 操作。

创建一个新图像

非常简单 :-)

var bitmap = try Bitmap(width: 640, height: 480)

将图像加载到位图

支持 NSImageUIImageCGImageSource 在加载时支持的任何文件格式。

// From a file...
var bitmap = try Bitmap(fileURL: ...)

// From image data
var bitmap = try Bitmap(imageData: ...)

保存位图

支持 NSImageUIImageCGImageSource 在保存时支持的任何文件格式。

Bitmap 提供了写入一些不同格式的方法,例如 png。位图上的 representation 属性包含生成不同格式图像数据的方法。

var bitmap = try Bitmap(fileURL: ...)
...
let pngData = bitmap.representation?.png()

绘制到位图

使用 CG 方法绘制到位图的上下文中

var bitmap = try Bitmap(width: 640, height: 480)
bitmap.draw { ctx in
   ctx.setFillColor(.black)
   ctx.fill([CGRect(x: 5, y: 5, width: 20, height: 20)])
}

将图像绘制到位图

var bitmap = try Bitmap(width: 640, height: 480)
// Draw an image into a defined rectangle (with optional scaling types aspectFit, aspectFill, axes independent)
bitmap.drawImage(image, in: CGRect(x: 50, y: 50, width: 100, height: 100))
// Draw a bitmap at a point
bitmap.drawBitmap(bitmap, at: CGPoint(x: 300, y: 300))

获取/设置单个像素

您可以使用下标或 Bitmap 上的 get/setPixel 方法直接访问位图中的像素信息。

var bitmap = Bitmap(...)

// Retrieve the color of the pixel at x = 4, y = 3.
let rgbaPixel = bitmap[4, 3]   // or bitmap.getPixel(x: 4, y: 3)

// Set the color of the pixel at x = 4, y = 3. Only available when `bitmap` is mutable
bitmap[4, 3] = Bitmap.RGBA(r: 255, g: 0, b: 0, a: 255)   // or bitmap.setPixel(x: 4, y: 3, ...)

位图操作

Bitmap 提供了一些内置操作(例如旋转、着色),这些操作作用于 Bitmap 实例。

可变 (Mutable)

可变函数作用于 Bitmap 变量。 每个方法都会修改原始位图实例。

// Load an image, rotate it and convert it to grayscale
var bitmap = try Bitmap(fileURL: ...)
try bitmap.rotate(by: 1.4)
try bitmap.grayscale()

不可变 (Immutable)

不可变函数处理位图的副本并返回该副本。 原始位图(可以是 let 变量)保持不变。

不可变函数变体在标题中以“ing”命名,例如 tinting()scaling()

// Load an image, rotate it and convert it to grayscale
let bitmap = try Bitmap(fileURL: ...)
let rotated = try bitmap.rotating(by: 1.4)
let grayscale = try rotated.grayscaling()

这允许在位图上进行函数式风格的链式调用。

// Functional style
let bitmap = try Bitmap(fileURL: ...)
	.rotating(by: 1.4)
	.grayscaling()

可用的位图操作函数

... 以及更多!

Sendable 支持

您将无法直接在任务之间发送 Bitmap 对象。 这是因为 Bitmap 在内部缓存了一个 CGContext 实例,以提高性能并减少内存占用。

在内部,Bitmap 将像素信息保存在符合 SendableBitmap.RGBAData 对象中。 该对象可以在任务之间安全传递,并可以轻松地重新构建为新的 Bitmap 对象。

var myBitmap = try Bitmap(...)
let bitmapData = myBitmap.bitmapData

// Pass `bitmapData` to another Task

var myBitmap = try Bitmap(bitmapData)

许可协议 (License)

MIT License

Copyright (c) 2024 Darren Ford

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.