2009-06-01 28 views
6

Necesito crear una representación de cadena base64 de un objeto de cacao de NSImage. Cuál es la mejor manera de manejar esto, la documentación de Apple parece ser un poco corta sobre el tema (o simplemente no puedo encontrarlo). La codificación de Base64 parece bastante compleja desde el exterior.NSImage a Base64

Cualquier ayuda sería muy apreciada.

Saludos Alex

EDITAR

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

Respuesta

4

Un NSImage es un objeto muy abstracto. A NSImage realmente no le importa si se trata de una imagen ráster o una imagen vectorial; un objeto NSImage puede incluso tener representaciones ráster, vector, e incluso programáticas a la vez, es así de general.

Antes de que pueda generar datos Base64, debe decidir qué desea codificar.

El primer paso es decidir si desea codificar un ráster o vectores. El primero es bastante fácil, y supongo que es probablemente lo que querías decir. Sin embargo, un NSImage podría provenir de una fuente vectorial, como un documento PDF.

Si sabe que creó la imagen a partir de una fuente de ráster, puede simplemente codificar esa fuente de datos.

Si proviene de una fuente vectorial, aún puede codificar eso si sabe que la aplicación en el extremo de decodificación podrá manejarlo (por ejemplo, si se trata de otra aplicación Cocoa o Cocoa Touch). Por otro lado, si la aplicación en el extremo de decodificación puede no ser capaz de manejar datos vectoriales, entonces debe evitar esta táctica.

La única solución que funciona en todos los casos es utilizarNSBitmapImageRep-create a raster capture de la imagen. Bloquea el foco en la imagen, luego crea un NSBitmapImageRep usando ese método, luego desbloquea el foco. Luego, use representationUsingType:properties: para generar datos PNG (o el formato apropiado) para la imagen. Luego Base64-codifica los datos PNG (o cualquier formato).

+0

supongo que Alex no quiere base64 codificar la imagen para sus propios fines, pero para cumplir el contrato de algún receptor, por ejemplo un servicio web. Siendo ese el caso, tendrá que basar64 exactamente en lo que espera el servicio web (probablemente datos JPG o PNG). Dudo que haya mucha necesidad de especular sobre la variedad de formas de codificar una imagen, pero tal vez Alex confirme de una forma u otra. – danielpunkass

+0

Hola chicos, creo que la codificación base64 funciona correctamente con el código de dribin.org, pero mientras wordpress acepta y crea el archivo, no es una imagen. http://alexmillsdesign.files.wordpress.com/2009/06/quickicon5.jpg Creo que no obtengo los datos correctos del objeto NSImage así que cambié mi código que está en la edición de mi pregunta original. Soy nuevo en la programación de imágenes, ¿dónde me estoy equivocando? –

+0

1. Use constantes con nombre (NSImageCompressionFactor, no @ "NSImageCompressionFactor"). 2. Use una instancia de NSNumber, no una cadena que contenga una representación decimal. 3. No es que importe, porque PNG no es compatible con NSImageCompressionFactor de todos modos. 4. Está creando y cargando datos PNG, no JPEG. Utilice .png como la extensión de nombre de archivo, o cree y cargue datos JPEG, no PNG. 5. Si descarga eso, encontrará que se trata de datos de base64. ¿Tal vez no necesites codificarlo en base64? –

2

Apple no proporciona ninguna ayuda particular en este caso, por lo que tiene que hacer frente a la complejidad por su cuenta, de una manera u otra.

Afortunadamente, hay algunos recursos disponibles para hacer esto más fácil. El primer enfoque es literalmente hacer la codificación y decodificación usted mismo. Google Caja de herramientas para Mac tiene un buen ejemplo de este enfoque y es posible que sea capaz de simplemente utilizar este archivo de origen tal y como son:

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

Si usted está construyendo sólo para el Mac, donde las bibliotecas son OpenSSH disponible, entonces se podría aprovechar algunas funciones en aquellas bibliotecas que hacer la codificación y decodificación:

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

2

tengo un montón de código, incluyendo la base 64 análisis sintáctico basado en la implementación de OmniFoundation, en my toolkit on github . En particular, mira Extensions/NSData + Base64.h.

1

Aquí es una extensión Swift 2 para convertir NSImage en una cadena 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([]) 
} 
} 
1

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: []) 
    } 
}