Swift使用Core Graphics转换图片格式
Swift使用Core Graphics转换图片格式

Swift使用Core Graphics转换图片格式

Core Graphics(ImageIO)在 macOS/iOS 中经常被用于图像处理,它不仅能进行绘制,还能完成 格式转换(例如 PNG → JPEG、TIFF → HEIC 等)。常见的流程是:

1、获取 CGImage

从 NSImage(macOS)或 UIImage(iOS)转换得到 CGImage。

2、创建 CGImageDestination

指定输出格式(JPEG、PNG、HEIC 等)。

3、设置压缩参数

比如 JPEG 的质量(kCGImageDestinationLossyCompressionQuality)。

4、写入并生成 Data 或文件

Swift实现Core Graphics

import AppKit
import ImageIO
import UniformTypeIdentifiers

/// 将 NSImage 转换为指定格式的 Data
/// - Parameters:
///   - image: 输入的 NSImage
///   - type: 目标格式(例如 kUTTypeJPEG / kUTTypePNG / kUTTypeHEIC)
///   - quality: 压缩质量(仅 lossy 格式有效,比如 JPEG/HEIC,取值 0~1)
/// - Returns: 转换后的 Data
func convertImageFormat(image: NSImage,
                        type: CFString,
                        quality: CGFloat = 1.0) -> Data? {
    
    // Step 1: 获取 CGImage
    guard let tiffData = image.tiffRepresentation,
          let bitmap = NSBitmapImageRep(data: tiffData),
          let cgImage = bitmap.cgImage else {
        print("无法获取 CGImage")
        return nil
    }
    
    // Step 2: 创建目标 Data 容器
    let outputData = NSMutableData()
    
    // Step 3: 创建 CGImageDestination
    guard let destination = CGImageDestinationCreateWithData(outputData, type, 1, nil) else {
        print("无法创建 CGImageDestination")
        return nil
    }
    
    // Step 4: 设置压缩参数
    let options: CFDictionary
    if type == kUTTypeJPEG || type == kUTTypeHEIC {
        options = [kCGImageDestinationLossyCompressionQuality: quality] as CFDictionary
    } else {
        options = [:] as CFDictionary
    }
    
    // Step 5: 添加图像并写入
    CGImageDestinationAddImage(destination, cgImage, options)
    CGImageDestinationFinalize(destination)
    
    return outputData as Data
}

/// 将图片直接写入文件
func saveImage(_ image: NSImage,
               to url: URL,
               type: CFString,
               quality: CGFloat = 1.0) -> Bool {
    guard let data = convertImageFormat(image: image, type: type, quality: quality) else {
        return false
    }
    do {
        try data.write(to: url)
        print("已保存到 \(url.path)")
        return true
    } catch {
        print("保存失败: \(error.localizedDescription)")
        return false
    }
}

使用示例

let image = NSImage(named: "example")!

// 转换为 JPEG,质量 0.8
let jpegURL = URL(fileURLWithPath: "/tmp/test.jpg")
saveImage(image, to: jpegURL, type: kUTTypeJPEG, quality: 0.8)

// 转换为 PNG(无损)
let pngURL = URL(fileURLWithPath: "/tmp/test.png")
saveImage(image, to: pngURL, type: kUTTypePNG)

// 转换为 HEIC(需要 macOS 10.13+)
if #available(macOS 10.13, *) {
    let heicURL = URL(fileURLWithPath: "/tmp/test.heic")
    saveImage(image, to: heicURL, type: kUTTypeHEIC, quality: 0.7)
}

支持的目标格式

在 Core Graphics / ImageIO 框架中,支持的图片格式主要通过 UTType(Uniform Type Identifier)来标识。

常用 Core Graphics 输出格式(通过 CGImageDestination):

1、JPEG:kUTTypeJPEG,扩展名 .jpg / .jpeg,有损压缩,可设置质量(0~1);

2、PNG:kUTTypePNG,扩展名 .png,无损压缩,透明支持;

3、TIFF:kUTTypeTIFF,扩展名 .tif / .tiff,无损,可多页(多帧);

4、GIF:kUTTypeGIF,扩展名 .gif,支持动画,但 Core Graphics 只能生成单帧;

5、BMP:kUTTypeBMP,扩展名 .bmp,无损,Windows 位图;

6、ICO:kUTTypeICO,扩展名 .ico,Windows 图标文件;

7、HEIF:kUTTypeHEIF,扩展名 .heif,HEIF 容器,可存储 JPEG/HEVC 图像;

8、HEIC:kUTTypeHEIC,扩展名 .heic,HEIF + HEVC 编码(iOS 11+/macOS 10.13+);

9、JPEG 2000:kUTTypeJPEG2000,扩展名 .jp2 / .j2k / .jpf / .jpx / .jpm,支持无损和有损压缩;

10、PDF:kUTTypePDF,扩展名 .pdf,矢量图或嵌入位图;

11、RAW:kUTTypeRawImage,扩展名 .raw / .cr2 / .nef / .arw / .dng / .orf / .rw2,相机原始格式,需要支持相机 RAW。

总结

Swift使用Core Graphics,可以实现多种不同图片格式之间的切换。

在macOS 12以后,Apple弃用了老的kUTTypeXXX变量,统一改用UTType。如果继续使用kUTTypeXXX变量,就会提示:

guard let destination = CGImageDestinationCreateWithData(outputData, kUTTypeJPEG , 1, nil) else {   // 'kUTTypeJPEG' was deprecated in macOS 12.0: Use UTTypeJPEG or UTType.jpeg (swift) instead.

替代写法:使用UTType。

引入UTType框架:

import UniformTypeIdentifiers

使用UTType写法:

guard let destination = CGImageDestinationCreateWithData(
    outputData,
    UTType.jpeg.identifier as CFString, // 新的写法
    1,
    nil
) else {
    print("无法创建 CGImageDestination")
    completion(false)
    return
}

如果不想要手写.identifier as CFString,可以继续使用旧的kUTTypeJPEG,只是会有提示信息。

相关文章

Apple二维图像绘制框架Core Graphics:https://fangjunyu.com/2024/12/16/apple%e4%ba%8c%e7%bb%b4%e5%9b%be%e5%83%8f%e7%bb%98%e5%88%b6%e6%a1%86%e6%9e%b6core-graphics/

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注