NSImage к Base64 - PullRequest
       42

NSImage к Base64

6 голосов
/ 01 июня 2009

Мне нужно создать строковое представление base64 объекта какао NSImage. Что является лучшим способом справиться с этим, документация Apple, кажется, немного короткая по этому вопросу (или я просто не могу ее найти). Внешняя кодировка Base64 кажется довольно сложной.

Любая помощь будет принята с благодарностью.

Приветствие Alex

EDIT

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];

Ответы [ 6 ]

4 голосов
/ 01 июня 2009

NSImage - очень абстрактный объект. NSImage действительно не волнует, является ли это растровым изображением или векторным изображением; объект NSImage может даже иметь растровые, векторные, и даже программные представления одновременно - это общее.

Прежде чем вы сможете сгенерировать данные Base64, вы должны решить что вы хотите кодировать.

Первый шаг - решить, хотите ли вы кодировать растр или векторы. Первое довольно легко, и я думаю, это, вероятно, то, что вы имели в виду. Однако NSImage мог быть получен из векторного источника, такого как документ PDF.

Если вы знаете, что создали изображение из растрового источника, вы можете просто закодировать эти исходные данные.

Если оно получено из векторного источника, вы все равно можете просто закодировать его, если знаете, что приложение на стороне декодирования сможет его обработать (например, если это другое приложение Cocoa или Cocoa Touch). С другой стороны, если приложение на стороне декодирования может не обрабатывать векторные данные, вам следует избегать этой тактики.

Единственное решение, которое работает во всех случаях , заключается в использовании NSBitmapImageRep до для создания растрового захвата изображения. Заблокируйте фокус на изображении, затем создайте NSBitmapImageRep, используя этот метод, затем разблокируйте фокус. Затем используйте presentationUsingType: properties: , чтобы сгенерировать данные PNG (или любой другой формат) для изображения. Затем Base64-кодирует данные PNG (или любой другой формат).

2 голосов
/ 01 июня 2009

У меня есть куча кода, включая разбор Base64, основанный на реализации в OmniFoundation, в моем наборе инструментов на github В частности, посмотрите на Extensions / NSData + Base64.h.

2 голосов
/ 01 июня 2009

Apple не предоставляет никакой конкретной помощи, поэтому вам придется решать сложность самостоятельно, так или иначе.

К счастью, есть некоторые ресурсы, чтобы сделать это проще. Первый подход заключается в буквальном кодировании и декодировании самостоятельно. Google Toolbox для 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/

1 голос
/ 31 августа 2018

Swift 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: []))
    }
}
1 голос
/ 28 сентября 2016

Swift 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: [])
    }
}
1 голос
/ 03 июля 2016

Вот расширение Swift 2 для преобразования NSImage в строку base64:

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([])
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...