La conversión a NSImage CIImage sin degradación de la calidad
-
03-10-2019 - |
Pregunta
Estoy tratando de convertir un NSImage a un CIImage. Cuando hago esto, parece que hay una enorme pérdida en la calidad de la imagen. Creo que es debido a la "TIFFRepresentation". ¿Alguien tiene un mejor método? Muchas gracias.
NSImage *image = [[NSImage alloc] initWithData:[someSource dataRepresentation]];
NSData * tiffData = [image TIFFRepresentation];
CIImage *backgroundCIImage = [[CIImage alloc] initWithData:tiffData];
CIContext *ciContext = [[NSGraphicsContext currentContext] CIContext];
[ciContext drawImage:backgroundCIImage atPoint:CGPointZero fromRect:someRect];
Solución 3
Finalmente resolvió el problema. Básicamente, permiten disponer de documentos pdf dos veces su resolución fuera de la pantalla normal y luego capturar la imagen representada por la vista. Para una imagen más detallada, simplemente aumentar el factor de escala. Por favor, vea el siguiente código para la prueba de concepto. Yo no muestro la CIImage pero una vez que el mapa de bits, sólo tiene que utilizar el método CIImage para crear el CIImage del mapa de bits.
NSImage *pdfImage = [[NSImage alloc] initWithData:[[aPDFView activePage] dataRepresentation]];
NSSize size = [pdfImage size];
NSRect imageRect = NSMakeRect(0, 0, size.width, size.height);
imageRect.size.width *= 2; //Twice the scale factor
imageRect.size.height *= 2; //Twice the scale factor
PDFDocument *pageDocument = [[[PDFDocument alloc] init] autorelease];
[pageDocument insertPage:[aPDFView activePage] atIndex:0];
PDFView *pageView = [[[PDFView alloc] init] autorelease];
[pageView setDocument:pageDocument];
[pageView setAutoScales:YES];
NSWindow *offscreenWindow = [[NSWindow alloc] initWithContentRect:imageRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreRetained
defer:NO];
[offscreenWindow setContentView:pageView];
[offscreenWindow display];
[[offscreenWindow contentView] display]; // Draw to the backing buffer
// Create the NSBitmapImageRep
[[offscreenWindow contentView] lockFocus];
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:imageRect];
// Clean up and delete the window, which is no longer needed.
[[offscreenWindow contentView] unlockFocus];
[compositeImage TIFFRepresentation]];
NSData *imageData = [rep representationUsingType: NSJPEGFileType properties: nil];
[imageData writeToFile:@"/Users/David/Desktop/out.jpg" atomically: YES];
[offscreenWindow release];
Otros consejos
Su problema es de hecho la conversión a TIFF. PDF es un formato vectorial, mientras que TIFF es mapa de bits, por lo que un TIFF se verá borrosa en tamaños más grandes.
Su mejor apuesta es, probablemente, para obtener una CGImage del NSImage y crear el CIImage de eso. O eso, o simplemente crear el CIImage de los datos originales.
Trate de reemplazar la línea
NSData * tiffData = [image TIFFRepresentation];
con
NSData * tiffData = [image TIFFRepresentationUsingCompression: NSTIFFCompressionNone factor: 0.0f];
porque la documentación estados que TIFFRepresentation utiliza la opción de compresión TIFF asociado a cada representación de la imagen, que podría no ser NSTIFFCompressionNone. Por lo tanto, debe ser explícito sobre el deseo de la tiffData sin comprimir.