예제 #1
0
int generatePages(const char *documentPath) {
	int error = 0;
	CFStringRef path = CFStringCreateWithCString(
		NULL, documentPath, kCFStringEncodingUTF8
	);
	CFURLRef url = CFURLCreateWithFileSystemPath(
		NULL, path, kCFURLPOSIXPathStyle, 0
	);
	CGPDFDocumentRef document = CGPDFDocumentCreateWithURL(url);

	if (document != NULL) {
		size_t lastPageIndex = CGPDFDocumentGetNumberOfPages(document) + 1;
		CFStringRef pdfPath = CFSTR("document.pdf");
		CFURLRef pdfUrl = CFURLCreateWithFileSystemPath(
			NULL, pdfPath, kCFURLPOSIXPathStyle, 0
		);
		CGContextRef context = CGPDFContextCreateWithURL(pdfUrl, NULL, NULL);

		printf("Compressing PDF\n");
		for(size_t pageIndex = 1; pageIndex < lastPageIndex; ++pageIndex) {
			CGPDFPageRef page = CGPDFDocumentGetPage(document, pageIndex);
			const CGRect cropBox = CGPDFPageGetBoxRect(page, kCGPDFCropBox);

			printf("Adding page %lu\n", pageIndex);
			CGContextBeginPage(context, &cropBox);
			CGContextDrawPDFPage(context, page);
			CGContextEndPage(context);
		}

		CGContextRelease(context);
		if (pdfUrl != NULL) CFRelease(pdfUrl);
		if (pdfPath != NULL) CFRelease(pdfPath);
		CGPDFDocumentRelease(document);
	} else {
		fprintf(stderr, "Cannot open PDF document\n");
		error = 1;
	}

	if(url != NULL) CFRelease(url);
	if(path != NULL) CFRelease(path);

	return error;
}
예제 #2
0
/* Draw the source PDF document into the context and then draw the stamp PDF document
on top of it. When drawing the stamp on top, place it along the diagonal from the lower
left corner to the upper right corner and center its media rect to the center of that
diagonal. */
void StampWithPDFDocument(CGContextRef context, 
			CGPDFDocumentRef sourcePDFDoc, 
			CGPDFDocumentRef stampFileDoc, CGRect stampMediaRect)
{
    CGRect pageRect;
    float angle;
    size_t i, numPages = CGPDFDocumentGetNumberOfPages(sourcePDFDoc);
    
    // Loop over document pages and stamp each one appropriately.
    for(i = 1 ; i <= numPages ; i++)
    {
		// Use the page rectangle of each page from the source to compute
		// the destination media box for each page and the location of
		// the stamp.
		CGRect pageRect = CGPDFDocumentGetMediaBox(sourcePDFDoc, i);
		CGContextBeginPage(context, &pageRect);
		CGContextSaveGState(context);
			// Clip to the media box of the page.
			CGContextClipToRect(context, pageRect);	    
			// First draw the content of the source document.
			CGContextDrawPDFDocument(context, pageRect, sourcePDFDoc, i);
			// Translate to center of destination rect, that is the center of 
			// the media box of content to draw on top of.
			CGContextTranslateCTM(context, 
				pageRect.size.width/2, pageRect.size.height/2);
			// Compute angle of the diagonal across the destination page.
			angle = atan(pageRect.size.height/pageRect.size.width);
			// Rotate by an amount so that drawn content goes along a diagonal
			// axis across the page.
			CGContextRotateCTM(context, angle);
			// Move the origin so that the media box of the PDF to stamp
			// is centered around center point of destination.
			CGContextTranslateCTM(context, 
			-stampMediaRect.size.width/2, 
			-stampMediaRect.size.height/2);
			// Now draw the document to stamp with on top of original content.
			CGContextDrawPDFDocument(context, stampMediaRect, 
					stampFileDoc, 1);
		CGContextRestoreGState(context);
		CGContextEndPage(context);
    }
}
예제 #3
0
파일: main.c 프로젝트: ianlevesque/pdf2png
int main (int argc, const char * argv[])
{
    if(argc >= 2) {
        CGPDFDocumentRef doc = CGPDFDocumentCreateWithProvider(CGDataProviderCreateWithFilename(argv[1]));
        size_t pages = CGPDFDocumentGetNumberOfPages(doc);
        
        printf("%lu pages\n", pages);
        
        for(size_t i = 1; i <= pages; i++) {
            char filename[1024];
            
            snprintf(filename, 1024, "%s.%03lu.png", argv[1], i);
            
            printf("writing file: %s\n", filename);
         
            CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
            CGContextRef context = CGBitmapContextCreate(NULL, SIZE, SIZE, 8, 4 * SIZE, colorSpace, kCGImageAlphaPremultipliedLast);
            CGColorSpaceRelease(colorSpace);
            
            CGContextDrawPDFDocument(context, CGRectMake(0, 0, SIZE, SIZE), doc, (int)i);
            
            CGImageRef image = CGBitmapContextCreateImage(context);
            
            CGImageDestinationRef dest = CGImageDestinationCreateWithURL(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFStringCreateWithCString(kCFAllocatorDefault, filename, kCFStringEncodingASCII), kCFURLPOSIXPathStyle, false), kUTTypePNG, 1, NULL);
            
            CGImageDestinationAddImage(dest, image, NULL);
            
            CGImageDestinationFinalize(dest);
            
            CGImageRelease(image);
            CGContextRelease(context);
        }
        
        CGPDFDocumentRelease(doc);
    } else {
        printf("pdf2png [filename]\n");
        return 1;
    }
    
    return 0;
}
예제 #4
0
int PDFDocumentImage::pageCount() const
{
    return m_document ? CGPDFDocumentGetNumberOfPages(m_document) : 0;
}
예제 #5
0
unsigned PDFDocumentImage::pageCount() const
{
    return CGPDFDocumentGetNumberOfPages(m_document.get());
}
예제 #6
0
void dumpPageStreams(CFURLRef url, FILE *outFile)
{
    CGPDFDocumentRef pdfDoc = NULL;
    CGPDFOperatorTableRef table = NULL;
    MyDataScan myData;
    size_t totalImages, totPages, i;

    // Create a CGPDFDocumentRef from the input PDF file.
    pdfDoc = CGPDFDocumentCreateWithURL(url);
    if(!pdfDoc){
		fprintf(stderr, "Couldn't open PDF document!\n"); return;
    }
    // Create the operator table with the needed callbacks.
    table = createMyOperatorTable();
    if(!table){
		CGPDFDocumentRelease(pdfDoc);
		fprintf(stderr, "Couldn't create operator table\n!"); return;
    }
    // Initialize the count of the images.
    totalImages = 0;

    // Obtain the total number of pages for the document.
    totPages = CGPDFDocumentGetNumberOfPages(pdfDoc);

    // Loop over all the pages in the document, scanning the
    // content stream of each one.
    for(i = 1; i <= totPages; i++){
		CGPDFScannerRef scanner = NULL;
		// Get the PDF page for this page in the document.
		CGPDFPageRef p = CGPDFDocumentGetPage(pdfDoc, i);
		// Create a reference to the content stream for this page.
		CGPDFContentStreamRef cs = CGPDFContentStreamCreateWithPage(p);
		if(!cs){
			CGPDFOperatorTableRelease(table);
			CGPDFDocumentRelease(pdfDoc);
			fprintf(stderr, 
			"Couldn't create content stream for page #%zd!\n", i);
			return;
		}
		// Create a scanner for this PDF document page.
		scanner = CGPDFScannerCreate(cs, table, &myData);
		if(!scanner){
			CGPDFContentStreamRelease(cs);
			CGPDFOperatorTableRelease(table);
			CGPDFDocumentRelease(pdfDoc);
			fprintf(stderr, "Couldn't create scanner for page #%zd!\n", i);
			return;
		}
		// Initialize the counters of images for this page.
		myData.numImagesWithColorThisPage = 0;
		myData.numImageMasksThisPage =  0;
		myData.numImagesMaskedWithMaskThisPage =  0;
		myData.numImagesMaskedWithColorsThisPage = 0;
	
		/* 	CGPDFScannerScan causes Quartz to scan the content stream,
			calling the callbacks in the table when the corresponding
			operator is encountered. Once the content stream for the
			page has been consumed or Quartz detects a malformed 
			content stream, CGPDFScannerScan returns. 
		*/
		if(!CGPDFScannerScan(scanner)){
			fprintf(stderr, "Scanner couldn't scan all of page #%zd!\n", i);
		}
		// Print the results for this page.
		printPageResults(outFile, myData, i);
		
		// Update the total count of images with the count of the
		// images on this page.
		totalImages += 
			myData.numImagesWithColorThisPage + 
			myData.numImageMasksThisPage +
			myData.numImagesMaskedWithMaskThisPage +
			myData.numImagesMaskedWithColorsThisPage;
	
		// Once the page has been scanned, release the 
		// scanner for this page.
		CGPDFScannerRelease(scanner);
		// Release the content stream for this page.
		CGPDFContentStreamRelease(cs);
		// Done with this page; loop to next page.
    }
    printDocResults(outFile, totPages, totalImages);

    // Release the operator table this code created.
    CGPDFOperatorTableRelease(table);
    // Release the input PDF CGPDFDocumentRef.
    CGPDFDocumentRelease(pdfDoc);
}