void PDFDocumentImage::setCurrentPage(int page) { if (!m_document) return; if (page == m_currentPage) return; if (!(page >= 0 && page < pageCount())) return; m_currentPage = page; CGPDFPageRef cgPage = CGPDFDocumentGetPage(m_document, page + 1); // get media box (guaranteed) m_mediaBox = CGPDFPageGetBoxRect(cgPage, kCGPDFMediaBox); // get crop box (not always there). if not, use media box CGRect r = CGPDFPageGetBoxRect(cgPage, kCGPDFCropBox); if (!CGRectIsEmpty(r)) m_cropBox = r; else m_cropBox = m_mediaBox; // get page rotation angle m_rotation = CGPDFPageGetRotationAngle(cgPage) * piFloat / 180.0f; // to radians }
void PDFDocumentImage::computeBoundsForCurrentPage() { CGPDFPageRef cgPage = CGPDFDocumentGetPage(m_document.get(), 1); CGRect mediaBox = CGPDFPageGetBoxRect(cgPage, kCGPDFMediaBox); // Get crop box (not always there). If not, use media box. CGRect r = CGPDFPageGetBoxRect(cgPage, kCGPDFCropBox); if (!CGRectIsEmpty(r)) m_cropBox = r; else m_cropBox = mediaBox; m_rotationDegrees = CGPDFPageGetRotationAngle(cgPage); }
CGAffineTransform PDFPageGetDrawingTransform(CGPDFPageRef page, CGPDFBox box, float scale) { CGRect boxRect = CGPDFPageGetBoxRect(page, box); int rotation = PDFPageGetRotation(page); CGAffineTransform transform = CGAffineTransformMakeScale(scale, scale); transform = CGAffineTransformRotate(transform, -(rotation * M_PI_2)); switch (rotation) { case 1: transform = CGAffineTransformTranslate(transform, -CGRectGetWidth(boxRect), 0); break; case 2: transform = CGAffineTransformTranslate(transform, -CGRectGetWidth(boxRect), 0); transform = CGAffineTransformTranslate(transform, 0, -CGRectGetHeight(boxRect)); break; case 3: transform = CGAffineTransformTranslate(transform, 0, -CGRectGetHeight(boxRect)); break; default: break; } transform = CGAffineTransformTranslate(transform, -boxRect.origin.x, -boxRect.origin.y); return transform; }
CGSize PDFPageGetSize(CGPDFPageRef page, CGPDFBox box) { CGRect boxRect = CGPDFPageGetBoxRect(page, box); int rotation = PDFPageGetRotation(page); bool invertSize = (rotation % 2) == 1; CGFloat width = invertSize ? CGRectGetHeight(boxRect) : CGRectGetWidth(boxRect); CGFloat height = invertSize ? CGRectGetWidth(boxRect) : CGRectGetHeight(boxRect); return CGSizeMake(width, height); }
/* For a URL corresponding to an existing PDF document on disk, create a CGPDFDocumentRef and obtain the media box of the first page. */ MyPDFData myCreatePDFSourceDocument(CFURLRef url) { MyPDFData myPDFData; myPDFData.pdfDoc = CGPDFDocumentCreateWithURL(url); if(myPDFData.pdfDoc){ myPDFData.mediaRect = CGPDFPageGetBoxRect(myPDFData.pdfDoc, kCGPDFMediaBox); // Make the media rect origin at 0,0. myPDFData.mediaRect.origin.x = myPDFData.mediaRect.origin.y = 0.; } return myPDFData; }
void wxMetafileRefData::UpdateDocumentFromData() { wxCFRef<CGDataProviderRef> provider(wxMacCGDataProviderCreateWithCFData(m_data)); m_pdfDoc.reset(CGPDFDocumentCreateWithProvider(provider)); if ( m_pdfDoc != NULL ) { CGPDFPageRef page = CGPDFDocumentGetPage( m_pdfDoc, 1 ); CGRect rect = CGPDFPageGetBoxRect ( page, kCGPDFMediaBox); m_width = static_cast<int>(rect.size.width); m_height = static_cast<int>(rect.size.height); } }
int main(int argc, char** argv) { if (argc <= 1 || !*(argv[1]) || 0 == strcmp(argv[1], "-")) { fprintf(stderr, "usage:\n\t%s INPUT_PDF_FILE_PATH [OUTPUT_PNG_PATH]\n", argv[0]); return 1; } const char* output = argc > 2 ? argv[2] : nullptr; CGDataProviderRef data = CGDataProviderCreateWithFilename(argv[1]); ASSERT(data); CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data); CGDataProviderRelease(data); ASSERT(pdf); CGPDFPageRef page = CGPDFDocumentGetPage(pdf, PAGE); ASSERT(page); CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); int w = (int)CGRectGetWidth(bounds); int h = (int)CGRectGetHeight(bounds); CGBitmapInfo info = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast; CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); ASSERT(cs); std::unique_ptr<uint32_t[]> bitmap(new uint32_t[w * h]); memset(bitmap.get(), 0xFF, 4 * w * h); CGContextRef ctx = CGBitmapContextCreate(bitmap.get(), w, h, 8, w * 4, cs, info); ASSERT(ctx); CGContextDrawPDFPage(ctx, page); CGPDFDocumentRelease(pdf); CGImageRef image = CGBitmapContextCreateImage(ctx); ASSERT(image); CGDataConsumerCallbacks procs; procs.putBytes = [](void* f, const void* buf, size_t s) { return fwrite(buf, 1, s, (FILE*)f); }; procs.releaseConsumer = [](void* info) { fclose((FILE*)info); }; FILE* ofile = (!output || !output[0] || 0 == strcmp(output, "-")) ? stdout : fopen(output, "wb"); ASSERT(ofile); CGDataConsumerRef consumer = CGDataConsumerCreate(ofile, &procs); ASSERT(consumer); CGImageDestinationRef dst = CGImageDestinationCreateWithDataConsumer(consumer, kUTTypePNG, 1, nullptr); CFRelease(consumer); ASSERT(dst); CGImageDestinationAddImage(dst, image, nullptr); ASSERT(CGImageDestinationFinalize(dst)); CFRelease(dst); CGImageRelease(image); CGColorSpaceRelease(cs); CGContextRelease(ctx); return 0; }
bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) { size_t size = stream->getLength(); void* ptr = sk_malloc_throw(size); stream->read(ptr, size); CGDataProviderRef data = CGDataProviderCreateWithData(NULL, ptr, size, CGDataProviderReleaseData_FromMalloc); if (NULL == data) { return false; } CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data); CGDataProviderRelease(data); if (NULL == pdf) { return false; } SkAutoPDFRelease releaseMe(pdf); CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1); if (NULL == page) { return false; } CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); int w = (int)CGRectGetWidth(bounds); int h = (int)CGRectGetHeight(bounds); SkBitmap bitmap; if (!bitmap.allocPixels(SkImageInfo::MakeN32Premul(w, h))) { return false; } bitmap.eraseColor(SK_ColorWHITE); size_t bitsPerComponent; CGBitmapInfo info; getBitmapInfo(bitmap, &bitsPerComponent, &info, NULL); CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); CGContextRef ctx = CGBitmapContextCreate(bitmap.getPixels(), w, h, bitsPerComponent, bitmap.rowBytes(), cs, info); CGColorSpaceRelease(cs); if (ctx) { CGContextDrawPDFPage(ctx, page); CGContextRelease(ctx); } output->swap(bitmap); return true; }
bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) { CGDataProviderRef data = SkCreateDataProviderFromStream(stream); if (NULL == data) { return false; } CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data); CGDataProviderRelease(data); if (NULL == pdf) { return false; } SkAutoPDFRelease releaseMe(pdf); CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1); if (NULL == page) { return false; } CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); int w = (int)CGRectGetWidth(bounds); int h = (int)CGRectGetHeight(bounds); SkBitmap bitmap; if (!bitmap.tryAllocN32Pixels(w, h)) { return false; } bitmap.eraseColor(SK_ColorWHITE); size_t bitsPerComponent; CGBitmapInfo info; getBitmapInfo(bitmap, &bitsPerComponent, &info, NULL); CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); CGContextRef ctx = CGBitmapContextCreate(bitmap.getPixels(), w, h, bitsPerComponent, bitmap.rowBytes(), cs, info); CGColorSpaceRelease(cs); if (ctx) { CGContextDrawPDFPage(ctx, page); CGContextRelease(ctx); } output->swap(bitmap); return true; }
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; }