2011-10-30 11 views
8

He utilizado los siguientes métodos para generar un PDF desde una UIView. Todas estas crean el PDF, pero pierde calidad:iOS - Generando PDF desde UIView por renderización pierde calidad

Método 1:

@implementation UIView(PDFWritingAdditions) 

- (void)renderInPDFFile:(NSString*)path 
{ 
    CGRect mediaBox = self.bounds; 
    CGContextRef ctx = CGPDFContextCreateWithURL((__bridge_retained CFURLRef)[NSURL fileURLWithPath:path], &mediaBox, NULL); 
    CGPDFPageRef page; 
    CGContextDrawPDFPage(ctx, page); 

    CGPDFContextBeginPage(ctx, NULL); 

    // Also tried following commented lines but no luck 
    // CGContextSetFlatness(ctx, 0.1); 
    // CGContextSetAllowsAntialiasing(ctx, YES); 
    // CGContextSetAllowsFontSmoothing(ctx, YES); 
    // CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); 
    CGContextScaleCTM(ctx, 1, -1); 
    CGContextTranslateCTM(ctx, 0, -mediaBox.size.height); 
    [self.layer renderInContext:ctx]; 
    CGPDFContextEndPage(ctx); 
    CFRelease(ctx); 
} 

@end 

Método 2:

- (void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename 
{ 
    // Creates a mutable data object for updating with binary data, like a byte array 
    NSMutableData *pdfData = [NSMutableData data]; 

    // Points the pdf converter to the mutable data object and to the UIView to be converted 
    UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil); 
    UIGraphicsBeginPDFPage(); 
    CGContextRef pdfContext = UIGraphicsGetCurrentContext(); 


    // draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData 

    [aView.layer renderInContext:pdfContext]; 

    // remove PDF rendering context 
    UIGraphicsEndPDFContext(); 

    // Retrieves the document directories from the iOS device 
    NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES); 

    NSString* documentDirectory = [documentDirectories objectAtIndex:0]; 
    NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename]; 

    // instructs the mutable data object to write its context to a file on disk 
    [pdfData writeToFile:documentDirectoryFilename atomically:YES]; 
    NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename); 
} 

Creo que puede faltar algunos ajustes para el contexto pdf, no estoy seguro. También he crear una imagen PNG de UIView con siguiente método, que es exactamente la misma calidad:

- (UIImage *)imageFromView:(UIView *)view 
{ 
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); 
    [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 

    UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 
    // Retrieves the document directories from the iOS device 
    NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES); 

    NSString* documentDirectory = [documentDirectories objectAtIndex:0]; 
    NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:@"pdf.png"]; 

    // instructs the mutable data object to write its context to a file on disk 
    [UIImagePNGRepresentation(img) writeToFile:documentDirectoryFilename atomically:YES]; 
    NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename); 
    return img; 
} 

Puede alguien ver lo que estoy haciendo mal? Gracias.

+0

¿Cómo se pierde calidad? –

+0

Aquí está el enlace de la vista original: y después del enlace en pdf: iEamin

+0

posible duplicado de [Alta calidad UIImage de PDF] (http://stackoverflow.com/questions/14152477/high-quality-uiimage-from-pdf) – nielsbot

Respuesta

2

¿Se está utilizando una pantalla Retina? Podría ser una cosa de contentsScale. Echar un vistazo a this SO post

EDITAR Ok, ahora que has publicado antes & después de fotos, veo que lo que quiere el UIView factura que pasarán a ser tan bonito, de alta calidad, datos vectoriales imprimibles en su PDF .

Estoy bastante seguro de que [CALayer renderInContext] siempre produce datos ráster, por lo que es mejor que construya el PDF manualmente. Y si está hablando de facturas de impuestos, ¿realmente desea que el diseño cambie con la próxima actualización de iOS?

Sin embargo, podría look at this answer, lo que sugiere a regañadientes el uso de UIView como un sistema de plantilla para su diseño en PDF.

+0

No, esto sucede con la visualización normal. – iEamin

+0

Ya he creado la vista manualmente para el pdf [ya que no se ha encontrado ninguna solución] y usé UIView para obtener puntos y color como referencias [de modo que si cambio algo en la vista no tengo que cambiar el código]. Pero el enlace de la imagen original que he agregado se genera utilizando el método "imageFromView" y también una imagen de trama. Entonces, mi punto es que "renderInContext" debería ser capaz de generar la misma calidad en formato pdf. También traté de crear pdf a partir de esa imagen, pero no tuve suerte. . . el mismo problema. – iEamin

+0

Debe crear el PDF desde las llamadas a CGContextFillRect, CTFontDrawGlyphs etc. renderInContext siempre creará archivos PDF ráster de resolución de pantalla de aspecto deficiente. –

0

Mirando sus imágenes de ejemplo, no estoy seguro de que sus expectativas sean correctas ... Su ventana de vista previa está parcialmente ampliada, mientras que usted está dibujando una imagen de mapa de bits en su PDF, por lo que verá 'bordes irregulares 'cuando amplía. Si ve el tamaño real (en el menú de vista en Vista previa, o Cmd-0), entonces debería ver una imagen más o menos idéntica a su captura de pantalla.

Sin embargo, lo que realmente desea hacer no es simplemente renderizar su mapa de bits UIView en el contexto de PDF, sino realizar el dibujo y el diseño de CoreGraphics directamente en el contexto de PDF. Consulte este tutorial http://www.raywenderlich.com/6818/how-to-create-a-pdf-with-quartz-2d-in-ios-5-tutorial-part-2 para ver un ejemplo. Esto asegurará que el texto y las líneas permanezcan nítidos cuando se amplíe y asegure un producto de calidad si está impreso en papel. Los gráficos vectoriales de Quartz2D son sus amigos aquí, ya que nunca obtendrá una alta calidad con un mapa de bits, al menos no sin crear un gran archivo PDF ...

0

bien, no es exactamente el mismo problema, pero Creo que la solución será similar

creo que esto es una víctima de High quality UIImage from PDF

Ver mi respuesta allí:

https://stackoverflow.com/a/14152516/210171

Cuando solicita al PDF su tamaño de página, obtiene un ancho/alto de para 72 PPI. Puede intentar crear un contexto que se amplíe utilizando una transformación de escala . Por ejemplo, si desea representar a 300 ppp, agregue una transformación de escala a escala por 300.0/72.0.

Si exporta como TIFF, podrá encapsular el PPI final (300) de la imagen generada.