MacOS图像显示类NSImage
MacOS图像显示类NSImage

MacOS图像显示类NSImage

NSImage 是 macOS 系统中 AppKit 框架提供的一个类,用于加载、显示和操作图像资源。它在 macOS 中的角色类似于 iOS 中的 UIImage,专为 macOS 的图形处理需求设计。

核心特点

1、图像加载与显示

可以从文件、数据、系统资源或网络加载图像。

支持常见图像格式,如 PNG、JPEG、GIF、TIFF 等。

2、分辨率独立

支持 macOS 的 Retina 显示,自动选择适合分辨率的图像资源。

3、图像绘制

支持在 macOS 图形上下文(如 NSView 或 NSWindow)中绘制图像。

4、多分辨率支持

可以存储并管理不同分辨率的图像资源,以便在不同屏幕环境下使用。

创建NSImage

1、创建空图像(指定尺寸)

let image = NSImage(size: NSSize(width: 100, height: 100))

2、从资源名称加载(仅限 Assets 或 Bundle)

let image = NSImage(named: "example")

3、从文件路径(字符串)加载图像

let image = NSImage(contentsOfFile: "/path/to/image.png")

NSImage(contentsOfFile:) 属于旧方法,不支持file:// 形式的URL,只接受字符串路径。

4、从文件路径(URL)加载图像

let image = NSImage(contentsOf: URL(string: "https://example.com/image.png"))

更现代的API,可以和URL类型搭配,推荐使用。

5、从Data加载

let image = NSImage(data: data)

6、从CGImage创建图像

let image = NSImage(cgImage: cgImage, size: NSSize(width: 100, height: 100))

7、从剪贴板读取图像

let image = NSImage(pasteboard: NSPasteboard)

常用属性

1、size:NSSize类型,图像的逻辑尺寸(点数,不一定等于像素);

2、representations:[NSImageRep]类型,所有已添加的图像表示(可以有多个尺寸或类型);

3、isTemplate:Bool类型,是否是模板图像(适配系统颜色);

4、isFlipped:Bool类型,坐标是否翻转(影响上下颠倒);

5、tiffRepresentation:Data?类型,图像的原始 TIFF 数据(二进制格式);

6、capInsets:NSEdgeInsets类型,设置拉伸边缘(macOS 11+);

7、alignmentRectInsets:NSEdgeInsets类型,对齐用的边距(影响 Auto Layout);

8、accessibilityDescription:String?类型,用于 VoiceOver 等辅助功能;

9、name():NSImage.Name?类型,获取图像注册的名字(通常用于系统图标)。

示例:

let image = NSImage(named: "example")!
print(image.size) // 打印图像尺寸
image.isTemplate = true // 设置为模板图像
if let tiffData = image.tiffRepresentation {
    print("TIFF 数据大小:\(tiffData.count) 字节")
}

常用方法

1、addRepresentation(_:):返回Void类型,添加一个 NSImageRep 图像数据表示;

2、lockFocus() / unlockFocus():返回Void类型,开始/结束在图像上绘图;

3、draw(in:) / draw(at:from:operation:fraction:):返回Void类型,在当前上下文中绘制图像;

4、bestRepresentation(for:context:hints:):返回NSImageRep?类型,获取适合当前情况的图像表示;

5、setSize(_:):返回Void类型,设置图像的逻辑尺寸。

示例:

let image = NSImage(size: NSSize(width: 100, height: 100))

image.lockFocus()
// 在图像上画一个红色圆圈
NSColor.red.set()
let path = NSBezierPath(ovalIn: NSRect(x: 10, y: 10, width: 80, height: 80))
path.fill()
image.unlockFocus()

let imageData = image.tiffRepresentation
try? imageData?.write(to: URL(fileURLWithPath: "/Users/you/Desktop/test.tiff"))

实际使用draw绘制图像的文章,请见《macOS使用NSImage绘制图像》。

使用场景

1、保存图像到文件

因为NSImage是一个容器,可能包含多个不同分辨率的图像,所以其本身无法直接导出 .png/ .jpg格式,不能直接写入文件。

所以需要使用tiffRepresentation转换为TIFF格式的Data数据,传递并初始化NSBitmapImageRep,然后使用NSBitmapImageRep转换为PNG数据,然后使用write方法保存图像。

func saveImage(_ image: NSImage, to url: URL) -> Bool {
    guard let tiffData = image.tiffRepresentation,
          let bitmap = NSBitmapImageRep(data: tiffData),
          let pngData = bitmap.representation(using: .png, properties: [:]) else {
        return false
    }

    do {
        try pngData.write(to: url)
        return true
    } catch {
        print("保存失败: \(error)")
        return false
    }
}

在SwiftUI中使用NSImage

let nsImage = NSImage(named: "example")!
Image(nsImage: nsImage)

注意,在SwiftUI中不要直接使用NSImage显示,因为NSImage是一个处理图片的核心类,不是显示图片的。

和SwiftUI Image转换问题

当开发SwiftUI的macOS应用时,推荐使用NSImage。

因为SwiftUI的Image类型不能直接转换为NSImage,NSImage可以转换为Image类型。

SwiftUI的Image:

let image = Image("example")

只是 UI 的描述结构(像个“图像的占位符”)。

它内部可能来自:资源名称(Image(“xxx”)),NSImage / UIImage或者CGImage,因此它就失去了图像来源的可追溯性。

所以:一旦只拿到 Image,就无法获取其像素数据、NSData、NSImage 结构。

如果,一开始就保存图片为NSImage:

let nsImage = NSImage(contentsOf: someURL)
let swiftUIImage = Image(nsImage: nsImage)

这样既可以使用Image显示,也可以使用NSImage进行保存、压缩、预览、导出等处理。

总结

NSImage 是 macOS 应用开发中用于加载和操作图像的重要类,提供了一些 macOS 特有的功能(如多分辨率支持和直接绘制功能)。

支持PDF、矢量图、Retina多分辨率图,支持多帧动画。

在SwiftUI中,需要使用Image(nsImage:)显示图片。

相关文章

1、macOS位图类NSBitmapImageRep:https://fangjunyu.com/2025/07/10/macos%e4%bd%8d%e5%9b%be%e7%b1%bbnsbitmapimagerep/

2、macOS使用NSImage绘制图像:https://fangjunyu.com/2025/07/22/macos%e4%bd%bf%e7%94%a8nsimage%e7%bb%98%e5%88%b6%e5%9b%be%e5%83%8f/

   

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

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

发表回复

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