Gestire i pdf con IOS - Maurizio Moriconi - WhyMCA

647 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
647
On SlideShare
0
From Embeds
0
Number of Embeds
58
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Gestire i pdf con IOS - Maurizio Moriconi - WhyMCA

  1. 1. Gestire i PDF con iOS Maurizio Moriconi - @bugman79 Mobilesoftgiovedì 24 maggio 12
  2. 2. Chi sono: Maurizio Moriconi • CTO presso Mobilesoft • Co-founder • Mobile Developer • Main Developer http://www.linkedin.com/in/bugman @bugman79 http://www.facebook.com/maurizio.moriconi 2giovedì 24 maggio 12
  3. 3. Editoria digitale 3giovedì 24 maggio 12
  4. 4. 4giovedì 24 maggio 12
  5. 5. Funzionalità MobilePaper • Visualizzazione in portrait e landscape (2 pagine affiancate) • Zoom della pagina tramite pinch o con doppio tap • Possibilità di passare alle pagine successive o precedenti • Visualizzazione delle pagine tramite elenco e/o miniature • Visualizzazione dellindice (capitoli e paragrafi del pdf) • Memorizzazione dei segnalibri (preferiti) • Scelta della musica di sottofondo • Inserimento di note • Ricerca di testo allinterno della rivista • Disponibile su iOS ed Android 5giovedì 24 maggio 12
  6. 6. Editoria su iOS • Varie possibilità: – App Native – Uso di PDF con eventuale aggiunta di elementi nativi (multimedia ed interazione) – HTML 5 6giovedì 24 maggio 12
  7. 7. Il formato Pdf • Portable Document Format • File basato su un linguaggio di descrizione pagina • Sviluppato da Adobe System nel 1993 • Nel 2007 è diventato standard ISO 32000 • Ci sono vari sottoformati (PDF/A, PDF/X, PDF/E...) 7giovedì 24 maggio 12
  8. 8. PDF/A • PDF/A (PDF/Archiving) per l’archiviazione a lungo termine (ha 2 sottoformati /A-1a /A-1b) • Standard ISO 19005-1:2005 dal 2005 • Basato sulla vesione 1.4 del formato PDF di Adobe • Documenti “auto contenuti” – Include i font che utilizza!! – Include immagini, colori, altri dati – Non ci sono fonti esterne • Nel sottoformato PDF/A-2 si basa PDF v. 1.7 8giovedì 24 maggio 12
  9. 9. PDF: specifiche http://www.adobe.com/devnet/pdf/ pdf_reference.html Ultima versione: PDF Reference, sixth edition APDF version 1.7 1310 pagine!!! 9giovedì 24 maggio 12
  10. 10. Uso della webview • Vantaggi – Facile da realizzare – Possibilità di usare pdf “online” – Funzionamento dei link interni • Svantaggi – Poca interazione lato utente – Scrollview verticale – Nessuna paginazione 10giovedì 24 maggio 12
  11. 11. Caricare Pdf in una webview NSString *pdfPath = [[NSBundle mainBundle] pathForResource:@"file" ofType:@"pdf"]; NSURL *url = [NSURL fileURLWithPath:pdfPath]; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; [webView loadRequest:urlRequest]; 11giovedì 24 maggio 12
  12. 12. Show me the code... 12giovedì 24 maggio 12
  13. 13. Uso di Quartz • Motore di rendering di Darwin chiamato “per gli amici” con il nome di Core Graphics • Quartz 2D: – libreria grafica ereditata da QuickDraw – usa il formato PDF per il disegno!!! – si basa sulla versione 1.4 Adobe PDF 13giovedì 24 maggio 12
  14. 14. Classi che ci interessano • CGPDFDocument • CGPDFPage • CGPDFObject • CGContext 14giovedì 24 maggio 12
  15. 15. Caricamento del Pdf #import <QuartzCore/QuartzCore.h> NSURL *pdfURL = [[NSBundle mainBundle] URLForResource:@"TestPage.pdf" withExtension:nil]; CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL); // Prendo la prima pagina CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1); CGPDFPageRetain(page); // Determino la grandezza del PDF CGRect pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); pdfScale = self.imageView.frame.size.width/pageRect.size.width; pageRect.size = CGSizeMake(pageRect.size.width*pdfScale, pageRect.size.height*pdfScale); 15giovedì 24 maggio 12
  16. 16. Visualizzazione base UIGraphicsBeginImageContext(pageRect.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0); CGContextFillRect(context,pageRect); CGContextSaveGState(context); CGContextTranslateCTM(context, 0.0, pageRect.size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextScaleCTM(context, pdfScale,pdfScale);! CGContextDrawPDFPage(context, page); CGContextRestoreGState(context); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); [self.imageView setImage:image]; CGPDFPageRelease(page); CGPDFDocumentRelease(pdf); 16giovedì 24 maggio 12
  17. 17. Show me the code... 17giovedì 24 maggio 12
  18. 18. Scorrimento pagine • Uso di scrollview con paginazione • Creare una classe per la singola pagina ereditando da UIView • Pre-caricare più pagine ma... • Attenzione alla memoria! – Scaricare / Caricare una “finestra” di pagine 18giovedì 24 maggio 12
  19. 19. Pdf View - (id)initWithFrame:(CGRect)frame andPdfPage:(CGPDFPageRef)page { self = [super initWithFrame:frame]; if (self) { pagina = page; pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); pdfScale = self.frame.size.width/pageRect.size.width; pageRect.size = CGSizeMake(pageRect.size.width*pdfScale, pageRect.size.height*pdfScale); } return self; } - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0); CGContextFillRect(context,pageRect); CGContextSaveGState(context); CGContextTranslateCTM(context, 0.0, pageRect.size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextScaleCTM(context, pdfScale,pdfScale);! CGContextDrawPDFPage(context, pagina); CGContextRestoreGState(context); } 19giovedì 24 maggio 12
  20. 20. Impostare numero di pagine NSURL *pdfURL = [[NSBundle mainBundle] URLForResource:@"test.pdf" withExtension:nil]; pdf = CGPDFDocumentCreateWithURL((__bridge CFURLRef)pdfURL); numberOfPages = CGPDFDocumentGetNumberOfPages(pdf); myScrollview.contentSize = CGSizeMake( self.myScrollview.frame.size.width * numberOfPages, self.myScrollview.frame.size.height); myScrollview.pagingEnabled = YES; 20giovedì 24 maggio 12
  21. 21. Show me the code... 21giovedì 24 maggio 12
  22. 22. Gestire lo Zoom • Scrollview con dentro Scrollviews :) – Ogni pagina è una scrollview! • Utilizzando per lo zoom il delegato: - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView 22giovedì 24 maggio 12
  23. 23. Zoom con doppio tap • Intercettarlo tramite touchesBegan • Permettere lo zoom in base a dove si è fatto il tap! • Tornare a zoom scale = 1 con ulteriore doppio tap 23giovedì 24 maggio 12
  24. 24. Zoom con doppio tap - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { ! CGPoint punto = [[touches anyObject] locationInView:self]; ! CGRect frameToZoom ; NSInteger radius = self.frame.size.width / 5; frameToZoom = CGRectMake(punto.x-radius, punto.y-radius, radius*2, radius*2); ! UITouch *touch = [touches anyObject]; ! if([touch tapCount] == 2) { if(self.zoomScale == 1.0) ! { ! ! [self zoomToRect:frameToZoom animated:YES]; } ! else ! { ! ! [self setZoomScale:1.0 animated:YES]; ! } } } 24giovedì 24 maggio 12
  25. 25. Show me the code... 25giovedì 24 maggio 12
  26. 26. il Pdf è vettoriale!!! 26giovedì 24 maggio 12
  27. 27. CATiledLayer • Presente dentro QuartzCore! • Poca documentazione (4 properties, 1 Class Method) • Esempio: Applicazione Mappe • Ogni view possiede un CALayer – CATiledLayer è una sottoclasse di CALayer! • Per il disegno usare drawLayer:inContext: 27giovedì 24 maggio 12
  28. 28. LevelofDetail e LevelOfDetailBias • Level Of Detail il num di livelli di dettaglio per il layer • Level Of Detail Bias è il num di livelli magnified di dettaglio per il layer • Ogni LODB/LOD è una potenza di due o più rispetto al livello di dettaglio 28giovedì 24 maggio 12
  29. 29. TileSize • E’ la grandezza massima di ogni singolo tile usato nel layer • Di base è 256x256 • Ci sono problemi con iPad 3 :( 29giovedì 24 maggio 12
  30. 30. LevelofDetail e LevelOfDetailBias • UIScrollview con zoom – minimumZoomScale 0.125f – maximumZoomScale 8.0f – Zoom di fattore 8 • Potremmo scegliere LevelOfDetail 7 e LevelOfDetailBias 3 – 7 configurazioni di level of detail – ogni livello è la metà di risoluzione del precedente – primi 3 sono a risoluzione “magnified” – il 4 è a risoluzione normale – gli ultimi 3 sono a risoluzione ridotta 30giovedì 24 maggio 12
  31. 31. Level 0 8192×8192 Level 1 4096×4096 Level 2 2048×2048 Level 3 1024×1024 Level 4 512×512 Level 5 256×256 Level 6 128×128 31giovedì 24 maggio 12
  32. 32. CATiledLayer #import <QuartzCore/QuartzCore.h> @implementation QuartzView - (id)initWithFrame:(CGRect)frame andPdfPage:(CGPDFPageRef)page { self = [super initWithFrame:frame]; if (self) { CATiledLayer *tiledLayer = (CATiledLayer *)[self layer]; tiledLayer.levelsOfDetail = 7; ! ! tiledLayer.levelsOfDetailBias = 3; ! ! tiledLayer.tileSize = CGSizeMake(512.0, 512.0); pagina = page; pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); pdfScale = self.frame.size.width/pageRect.size.width; pageRect.size = CGSizeMake(pageRect.size.width*pdfScale, pageRect.size.height*pdfScale); } return self; } 32giovedì 24 maggio 12
  33. 33. CATiledLayer + (Class)layerClass { ! return [CATiledLayer class]; } - (void)drawRect:(CGRect)rect { } -(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context { ! CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0); CGContextFillRect(context,pageRect); ! ! CGContextSaveGState(context); ! CGContextTranslateCTM(context, 0.0, pageRect.size.height); ! CGContextScaleCTM(context, 1.0, -1.0); ! ! CGContextScaleCTM(context, pdfScale,pdfScale);! ! CGContextDrawPDFPage(context, pagina); ! CGContextRestoreGState(context); } 33giovedì 24 maggio 12
  34. 34. Show me the code... 34giovedì 24 maggio 12
  35. 35. Metadati • Dalle specifiche sono presenti al capitolo 10.2 Metadata • Sono in un formato “particolare” • Si possono estrarre con CoreGraphics 8-) 1 0 obj << /Title ( PostScript Language Reference, Third Edition ) /Author (Adobe Systems Incorporated) /Creator (Adobe FrameMaker 5.5.3 for Power Macintosh®) /Producer (Acrobat Distiller 3.01 for Power Macintosh) /CreationDate (D:19970915110347-0800) /ModDate (D:19990209153925-0800) >> endobj 35giovedì 24 maggio 12
  36. 36. Metadati 36giovedì 24 maggio 12
  37. 37. Titolo ed autore del pdf CGPDFDictionaryRef info = CGPDFDocumentGetInfo(pdf); CGPDFStringRef titleStringRef; CGPDFDictionaryGetString(info, "Title", &titleStringRef); const unsigned char *titleCstring = CGPDFStringGetBytePtr(titleStringRef); printf("Titolo: %s", titleCstring); CGPDFStringRef authorStringRef; CGPDFDictionaryGetString(info, "Author", &authorStringRef); const unsigned char *authorCstring = CGPDFStringGetBytePtr(authorStringRef); printf("nAutore: %s", authorCstring); 37giovedì 24 maggio 12
  38. 38. Accesso ai dati PDF • CGPDFDocument • CGPDFDocumentGetCatalog • CGPDFPage • CGPDFPageGetDictionary • CGPDFObjectGetObject, CGPDFDictionaryGetBoolean, CGPDFDictionaryGetInteger, CGPDFDictionaryGetString, CGPDFDictionaryGetArray... 38giovedì 24 maggio 12
  39. 39. Indice • Non è sempre presente :) • In base alla versione ed al formato potrebbe cambiare... (gestire più casi!) • Dalle specifiche presente nel capitolo 8.2 Document-Level Navigation 39giovedì 24 maggio 12
  40. 40. Outline Document 40giovedì 24 maggio 12
  41. 41. Outline Item • Chiavi: – Title – Parent / Prev / Next – First / Last – Count – Dest / A / SE CGPDFDictionaryRef dict = CGPDFDocumentGetCatalog(pdf); CGPDFDictionaryRef ret; if( (CGPDFDictionaryGetDictionary(dict, "Outline", &ret)) || (CGPDFDictionaryGetDictionary(dict, "Outlines", &ret))) { } 41giovedì 24 maggio 12
  42. 42. Show me the code... 42giovedì 24 maggio 12
  43. 43. Altre possibilità... che non vedremo :) • Links • Annotations (cap. 8.4) • Thumbnail (cap 8.2.3) • Ricerca testuale (estrazione full text) 43giovedì 24 maggio 12

×