7

我需要创建一个 NSImage 可可对象的 base64 字符串表示。处理这个问题的最佳方法是什么,苹果文档似乎在这个主题上有点短(或者我只是找不到它)。从外部看,Base64 编码似乎相当复杂。

任何帮助将不胜感激。

干杯亚历克斯

编辑

NSArray *keys = [NSArray arrayWithObject:@"NSImageCompressionFactor"];
NSArray *objects = [NSArray arrayWithObject:@"1.0"];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];

NSImage *image = [[NSImage alloc] initWithContentsOfFile:[imageField stringValue]];
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithData:[image TIFFRepresentation]];
NSData *tiff_data = [imageRep representationUsingType:NSPNGFileType properties:dictionary];

NSString *base64 = [tiff_data encodeBase64WithNewlines:NO];
4

6 回答 6

4

NSImage 是一个非常抽象的对象。NSImage 并不真正关心它是光栅图像还是矢量图像;一个 NSImage 对象甚至可以同时拥有光栅、矢量甚至编程表示——就是这么普遍。

在生成 Base64 数据之前,您必须确定编码的内容。

第一步是决定是否要对栅格或矢量进行编码。前者很简单,我猜这可能就是你的意思。但是,NSImage 可能来自矢量源,例如 PDF 文档。

如果您知道您是从栅格源创建图像的,则只需对该源数据进行编码即可。

如果它来自矢量源,如果您知道解码端的应用程序能够处理它(例如,如果它是另一个 Cocoa 或 Cocoa Touch 应用程序),您仍然可以对其进行编码。另一方面,如果解码端的应用程序可能无法处理矢量数据,那么您应该避免这种策略。

适用于所有情况的一种解决方案是使用NSBitmapImageRep创建图像的光栅捕获。锁定图像上的焦点,然后使用该方法创建一个 NSBitmapImageRep,然后解锁焦点。然后,使用representationUsingType:properties:为图像生成PNG(或任何合适的格式)数据。然后对 PNG(或任何格式)数据进行 Base64 编码。

于 2009-06-01T17:12:17.993 回答
3

斯威夫特 4

extension NSImage {
    var base64String: String? {
        guard let rep = NSBitmapImageRep(
            bitmapDataPlanes: nil,
            pixelsWide: Int(size.width),
            pixelsHigh: Int(size.height),
            bitsPerSample: 8,
            samplesPerPixel: 4,
            hasAlpha: true,
            isPlanar: false,
            colorSpaceName: .calibratedRGB,
            bytesPerRow: 0,
            bitsPerPixel: 0
            ) else {
                print("Couldn't create bitmap representation")
                return nil
        }

        NSGraphicsContext.saveGraphicsState()
        NSGraphicsContext.current = NSGraphicsContext(bitmapImageRep: rep)
        draw(at: NSZeroPoint, from: NSZeroRect, operation: .sourceOver, fraction: 1.0)
        NSGraphicsContext.restoreGraphicsState()

        guard let data = rep.representation(using: NSBitmapImageRep.FileType.png, properties: [NSBitmapImageRep.PropertyKey.compressionFactor: 1.0]) else {
            print("Couldn't create PNG")
            return nil
        }

        // With prefix
        // return "data:image/png;base64,\(data.base64EncodedString(options: []))" 
        // Without prefix
        return data.base64EncodedString(options: []))
    }
}
于 2018-08-31T07:57:26.793 回答
2

Apple 在这里没有提供任何特别的帮助,因此您必须以一种或另一种方式自行解决复杂性。

幸运的是,有一些资源可以让这更容易。第一种方法是自己进行编码和解码。Google Toolbox for Mac 有一个很好的例子,你可以直接使用这个源文件:

http://code.google.com/p/google-toolbox-for-mac/source/browse/trunk/Foundation/GTMBase64.m

如果您只为 Mac 构建,其中 OpenSSH 库可用,那么您可以利用这些库中的一些功能来进行编码和解码:

http://www.dribin.org/dave/blog/archives/2006/03/12/base64_cocoa/

于 2009-06-01T14:32:04.850 回答
2

我在 github 上的工具包中有一堆代码,包括基于 OmniFoundation 中实现的 Base64 解析。特别是,请查看 Extensions/NSData+Base64.h。

于 2009-06-01T16:29:52.300 回答
1

这是一个将 NSImage 转换为 base64 字符串的 Swift 2 扩展:

private extension NSImage {
    var base64String:String? {
    guard let rep = NSBitmapImageRep(
        bitmapDataPlanes: nil,
        pixelsWide: Int(size.width),
        pixelsHigh: Int(size.height),
        bitsPerSample: 8,
        samplesPerPixel: 4,
        hasAlpha: true,
        isPlanar: false,
        colorSpaceName: NSDeviceRGBColorSpace,
        bytesPerRow: 0,
        bitsPerPixel: 0
        ) else {
            print("Couldn't create bitmap representation")
            return nil
    }

    NSGraphicsContext.saveGraphicsState()
    NSGraphicsContext.setCurrentContext(NSGraphicsContext(bitmapImageRep: rep))
    drawAtPoint(NSZeroPoint, fromRect: NSZeroRect, operation: .CompositeSourceOver, fraction: 1.0)
    NSGraphicsContext.restoreGraphicsState()

    guard let data = rep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: [NSImageCompressionFactor: 1.0]) else {
        print("Couldn't create PNG")
        return nil
    }
    return data.base64EncodedStringWithOptions([])
}
}
于 2016-07-02T23:52:14.693 回答
1

斯威夫特 3

extension NSImage {
    var base64String:String? {
        guard let rep = NSBitmapImageRep(
            bitmapDataPlanes: nil,
            pixelsWide: Int(size.width),
            pixelsHigh: Int(size.height),
            bitsPerSample: 8,
            samplesPerPixel: 4,
            hasAlpha: true,
            isPlanar: false,
            colorSpaceName: NSDeviceRGBColorSpace,
            bytesPerRow: 0,
            bitsPerPixel: 0
            ) else {
                print("Couldn't create bitmap representation")
                return nil
        }

        NSGraphicsContext.saveGraphicsState()
        NSGraphicsContext.setCurrent(NSGraphicsContext(bitmapImageRep: rep))
        draw(at: NSZeroPoint, from: NSZeroRect, operation: .sourceOver, fraction: 1.0)
        NSGraphicsContext.restoreGraphicsState()

        guard let data = rep.representation(using: NSBitmapImageFileType.PNG, properties: [NSImageCompressionFactor: 1.0]) else {
            print("Couldn't create PNG")
            return nil
        }

        return data.base64EncodedString(options: [])
    }
}
于 2016-09-28T13:25:51.560 回答