void QuartzBitmap_Output(QuartzDesc_t dev, QuartzBitmapDevice *qbd) { if(qbd->path && qbd->uti) { /* On 10.4+ we can employ the CGImageDestination API to create a variety of different bitmap formats */ #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 char buf[PATH_MAX+1]; snprintf(buf, PATH_MAX, qbd->path, qbd->page); buf[PATH_MAX] = '\0'; CFStringRef pathString = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8*) buf, strlen(buf), kCFStringEncodingUTF8, FALSE); CFURLRef path; if(CFStringFind(pathString, CFSTR("://"), 0).location != kCFNotFound) { CFStringRef pathEscaped = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, pathString, NULL, NULL, kCFStringEncodingUTF8); path = CFURLCreateWithString(kCFAllocatorDefault, pathEscaped, NULL); CFRelease(pathEscaped); } else { path = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*) buf, strlen(buf), FALSE); } CFRelease(pathString); CFStringRef scheme = CFURLCopyScheme(path); CFStringRef type = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8*) qbd->uti, strlen(qbd->uti), kCFStringEncodingUTF8, FALSE); CGImageRef image = CGBitmapContextCreateImage(qbd->bitmap); if(CFStringCompare(scheme,CFSTR("file"), 0) == 0) { /* file output */ CGImageDestinationRef dest = CGImageDestinationCreateWithURL(path, type, 1, NULL); if(dest) { CGImageDestinationAddImage(dest, image, NULL); CGImageDestinationFinalize(dest); CFRelease(dest); } else error(_("QuartzBitmap_Output - unable to open file '%s'"), buf); } else if(CFStringCompare(scheme, CFSTR("clipboard"), 0) == 0) { /* clipboard output */ CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0); CGImageDestinationRef dest = CGImageDestinationCreateWithData(data, type, 1, NULL); CGImageDestinationAddImage(dest, image, NULL); CGImageDestinationFinalize(dest); CFRelease(dest); PasteboardRef pb = NULL; if(PasteboardCreate(kPasteboardClipboard, &pb) == noErr) { PasteboardClear(pb); PasteboardSynchronize(pb); PasteboardPutItemFlavor(pb, (PasteboardItemID) 1, type, data, 0); } CFRelease(data); } else warning(_("not a supported scheme, no image data written")); CFRelease(scheme); CFRelease(type); CFRelease(path); CFRelease(image); #endif } }
static void quartz_format(GVJ_t *job) { /* image destination -> data consumer -> job's gvdevice */ /* data provider <- job's imagedata */ CGDataConsumerRef data_consumer = CGDataConsumerCreate(job, &device_data_consumer_callbacks); CGImageDestinationRef image_destination = CGImageDestinationCreateWithDataConsumer(data_consumer, format_uti[job->device.id], 1, NULL); CGDataProviderRef data_provider = CGDataProviderCreateDirect(job->imagedata, BYTES_PER_PIXEL * job->width * job->height, &memory_data_provider_callbacks); /* add the bitmap image to the destination and save it */ CGColorSpaceRef color_space = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); CGImageRef image = CGImageCreate ( job->width, /* width in pixels */ job->height, /* height in pixels */ BITS_PER_COMPONENT, /* bits per component */ BYTES_PER_PIXEL * 8, /* bits per pixel */ BYTES_PER_PIXEL * job->width, /* bytes per row: exactly width # of pixels */ color_space, /* color space: sRGB */ kCGImageAlphaPremultipliedFirst, /* bitmap info: corresponds to CAIRO_FORMAT_ARGB32 */ data_provider, /* data provider: from imagedata */ NULL, /* decode: don't remap colors */ FALSE, /* don't interpolate */ kCGRenderingIntentDefault /* rendering intent (what to do with out-of-gamut colors): default */ ); CGImageDestinationAddImage(image_destination, image, NULL); CGImageDestinationFinalize(image_destination); /* clean up */ CGImageRelease(image); CGColorSpaceRelease(color_space); CGDataProviderRelease(data_provider); if (image_destination) CFRelease(image_destination); CGDataConsumerRelease(data_consumer); }
/* Encode bitmaps via CGImageDestination. We setup a DataConsumer which writes to our SkWStream. Since we don't reference/own the SkWStream, our consumer must only live for the duration of the onEncode() method. */ bool SkImageEncoder_CG::onEncode(SkWStream* stream, const SkBitmap& bm, int quality) { CFStringRef type; switch (fType) { case kJPEG_Type: type = kUTTypeJPEG; break; case kPNG_Type: type = kUTTypePNG; break; default: return false; } CGImageDestinationRef dst = SkStreamToImageDestination(stream, type); if (NULL == dst) { return false; } SkAutoTCallVProc<const void, CFRelease> ardst(dst); CGImageRef image = SkCreateCGImageRef(bm); if (NULL == image) { return false; } SkAutoTCallVProc<CGImage, CGImageRelease> agimage(image); CGImageDestinationAddImage(dst, image, NULL); CGImageDestinationFinalize(dst); return true; }
//----------------------------------------------------------------------------- bool IPlatformBitmap::createMemoryPNGRepresentation (IPlatformBitmap* bitmap, void** ptr, uint32_t& size) { bool result = false; #if !TARGET_OS_IPHONE CGBitmap* cgBitmap = dynamic_cast<CGBitmap*> (bitmap); if (cgBitmap) { CGImageRef image = cgBitmap->getCGImage (); if (image) { CFMutableDataRef data = CFDataCreateMutable (NULL, 0); if (data) { CGImageDestinationRef dest = CGImageDestinationCreateWithData (data, kUTTypePNG, 1, 0); if (dest) { CGImageDestinationAddImage (dest, image, 0); if (CGImageDestinationFinalize (dest)) { size = (uint32_t)CFDataGetLength (data); *ptr = malloc (size); CFDataGetBytes (data, CFRangeMake (0, size), (UInt8*)*ptr); result = true; } CFRelease (dest); } CFRelease (data); } } } #endif return result; }
static String CGImageToDataURL(CGImageRef image, const String& mimeType, const double* quality) { RetainPtr<CFMutableDataRef> data(AdoptCF, CFDataCreateMutable(kCFAllocatorDefault, 0)); if (!data) return "data:,"; RetainPtr<CFStringRef> uti = utiFromMIMEType(mimeType); ASSERT(uti); RetainPtr<CGImageDestinationRef> destination(AdoptCF, CGImageDestinationCreateWithData(data.get(), uti.get(), 1, 0)); if (!destination) return "data:,"; RetainPtr<CFDictionaryRef> imageProperties = 0; if (CFEqual(uti.get(), jpegUTI()) && quality && *quality >= 0.0 && *quality <= 1.0) { // Apply the compression quality to the image destination. RetainPtr<CFNumberRef> compressionQuality(AdoptCF, CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, quality)); const void* key = kCGImageDestinationLossyCompressionQuality; const void* value = compressionQuality.get(); imageProperties.adoptCF(CFDictionaryCreate(0, &key, &value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); } // Setting kCGImageDestinationBackgroundColor to black in imageProperties would allow saving some math in the // calling functions, but it doesn't seem to work. CGImageDestinationAddImage(destination.get(), image, imageProperties.get()); CGImageDestinationFinalize(destination.get()); Vector<char> out; base64Encode(reinterpret_cast<const char*>(CFDataGetBytePtr(data.get())), CFDataGetLength(data.get()), out); return "data:" + mimeType + ";base64," + out; }
void wxBitmapDataObject::SetBitmap( const wxBitmap& rBitmap ) { Clear(); wxBitmapDataObjectBase::SetBitmap( rBitmap ); if (m_bitmap.IsOk()) { CGImageRef cgImageRef = (CGImageRef) m_bitmap.CreateCGImage(); CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0); CGImageDestinationRef destination = CGImageDestinationCreateWithData( data , kUTTypeTIFF , 1 , NULL ); if ( destination ) { CGImageDestinationAddImage( destination, cgImageRef, NULL ); CGImageDestinationFinalize( destination ); CFRelease( destination ); } m_pictHandle = NewHandle(CFDataGetLength(data)); if ( m_pictHandle ) { memcpy( *(Handle)m_pictHandle, (const char *)CFDataGetBytePtr(data), CFDataGetLength(data) ); } CFRelease( data ); CGImageRelease(cgImageRef); } }
static void printPNG(CGImageRef image) { RetainPtr<CFMutableDataRef> imageData(AdoptCF, CFDataCreateMutable(0, 0)); RetainPtr<CGImageDestinationRef> imageDest(AdoptCF, CGImageDestinationCreateWithData(imageData.get(), kUTTypePNG, 1, 0)); CGImageDestinationAddImage(imageDest.get(), image, 0); CGImageDestinationFinalize(imageDest.get()); printf("Content-Length: %lu\n", CFDataGetLength(imageData.get())); fwrite(CFDataGetBytePtr(imageData.get()), 1, CFDataGetLength(imageData.get()), stdout); }
/* Encode bitmaps via CGImageDestination. We setup a DataConsumer which writes to our SkWStream. Since we don't reference/own the SkWStream, our consumer must only live for the duration of the onEncode() method. */ bool SkEncodeImageWithCG(SkWStream* stream, const SkPixmap& pixmap, SkEncodedImageFormat format) { SkBitmap bm; if (!bm.installPixels(pixmap)) { return false; } bm.setImmutable(); CFStringRef type; switch (format) { case SkEncodedImageFormat::kICO: type = kUTTypeICO; break; case SkEncodedImageFormat::kBMP: type = kUTTypeBMP; break; case SkEncodedImageFormat::kGIF: type = kUTTypeGIF; break; case SkEncodedImageFormat::kJPEG: type = kUTTypeJPEG; break; case SkEncodedImageFormat::kPNG: // PNG encoding an ARGB_4444 bitmap gives the following errors in GM: // <Error>: CGImageDestinationAddImage image could not be converted to destination // format. // <Error>: CGImageDestinationFinalize image destination does not have enough images // So instead we copy to 8888. if (bm.colorType() == kARGB_4444_SkColorType) { SkBitmap bitmapN32; bitmapN32.allocPixels(bm.info().makeColorType(kN32_SkColorType)); bm.readPixels(bitmapN32.info(), bitmapN32.getPixels(), bitmapN32.rowBytes(), 0, 0); bm.swap(bitmapN32); } type = kUTTypePNG; break; default: return false; } CGImageDestinationRef dst = SkStreamToImageDestination(stream, type); if (nullptr == dst) { return false; } SkAutoTCallVProc<const void, CFRelease> ardst(dst); CGImageRef image = SkCreateCGImageRef(bm); if (nullptr == image) { return false; } SkAutoTCallVProc<CGImage, CGImageRelease> agimage(image); CGImageDestinationAddImage(dst, image, nullptr); return CGImageDestinationFinalize(dst); }
void wxBitmapDataObject::SetBitmap( const wxBitmap& rBitmap ) { Clear(); wxBitmapDataObjectBase::SetBitmap( rBitmap ); if (m_bitmap.Ok()) { #if wxMAC_USE_CORE_GRAPHICS CGImageRef cgImageRef = (CGImageRef) m_bitmap.CGImageCreate(); #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 if ( UMAGetSystemVersion() >= 0x1040 ) { CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0); CGImageDestinationRef destination = CGImageDestinationCreateWithData( data , kUTTypeTIFF , 1 , NULL ); if ( destination ) { CGImageDestinationAddImage( destination, cgImageRef, NULL ); CGImageDestinationFinalize( destination ); CFRelease( destination ); } m_pictHandle = NewHandle(CFDataGetLength(data)); if ( m_pictHandle ) { memcpy( *(Handle)m_pictHandle, (const char *)CFDataGetBytePtr(data), CFDataGetLength(data) ); } CFRelease( data ); } else #endif #ifndef __LP64__ { // export as TIFF GraphicsExportComponent exporter = 0; OSStatus err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypeTIFF, &exporter); if (noErr == err) { m_pictHandle = NewHandle(0); if ( m_pictHandle ) { err = GraphicsExportSetInputCGImage( exporter, cgImageRef); err = GraphicsExportSetOutputHandle(exporter, (Handle)m_pictHandle); err = GraphicsExportDoExport(exporter, NULL); } CloseComponent( exporter ); } } #endif CGImageRelease(cgImageRef); #else m_pictHandle = m_bitmap.GetBitmapData()->GetPictHandle(); m_pictCreated = false; #endif } }
err_t MacCGEncoder::writeImage(const Image& image) { Image tmp; if (image.isEmpty()) return ERR_IMAGE_INVALID_SIZE; err_t err = ERR_OK; CGDataConsumerRef cgConsumer = NULL; CGImageDestinationRef cgDestination = NULL; CGImageRef cgImage = NULL; cgConsumer = CGDataConsumerCreate(this, &_consumerCallbacks); if (FOG_IS_NULL(cgConsumer)) { err = ERR_RT_OUT_OF_MEMORY; goto _End; } cgDestination = CGImageDestinationCreateWithDataConsumer(cgConsumer, static_cast<MacCGCodecProvider*>(_provider)->getUTType(), 1, NULL); CFRelease(cgConsumer); if (FOG_IS_NULL(cgDestination)) { err = ERR_RT_OUT_OF_MEMORY; goto _End; } if (image.getType() == IMAGE_TYPE_MAC_CG) cgImage = static_cast<CGImageRef>(const_cast<Image&>(image).getHandle()); if (FOG_IS_NULL(cgImage)) { err = image.toCGImage(&cgImage); if (FOG_IS_ERROR(err)) goto _End; } CGImageDestinationAddImage(cgDestination, cgImage, NULL); if (!CGImageDestinationFinalize(cgDestination)) { err = ERR_IO_CANT_WRITE; } _End: CFRelease(cgDestination); if (err == ERR_OK) updateProgress(1.0f); return err; }
static void dumpBitmap(CGContextRef bitmapContext, const char* checksum) { RetainPtr<CGImageRef> image = adoptCF(CGBitmapContextCreateImage(bitmapContext)); RetainPtr<CFMutableDataRef> imageData = adoptCF(CFDataCreateMutable(0, 0)); RetainPtr<CGImageDestinationRef> imageDest = adoptCF(CGImageDestinationCreateWithData(imageData.get(), kUTTypePNG, 1, 0)); CGImageDestinationAddImage(imageDest.get(), image.get(), 0); CGImageDestinationFinalize(imageDest.get()); const unsigned char* data = CFDataGetBytePtr(imageData.get()); const size_t dataLength = CFDataGetLength(imageData.get()); printPNG(data, dataLength, checksum); }
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; }
/* Encode bitmaps via CGImageDestination. We setup a DataConsumer which writes to our SkWStream. Since we don't reference/own the SkWStream, our consumer must only live for the duration of the onEncode() method. */ bool SkImageEncoder_CG::onEncode(SkWStream* stream, const SkBitmap& bm, int quality) { // Used for converting a bitmap to 8888. const SkBitmap* bmPtr = &bm; SkBitmap bitmap8888; CFStringRef type; switch (fType) { case kICO_Type: type = kUTTypeICO; break; case kBMP_Type: type = kUTTypeBMP; break; case kGIF_Type: type = kUTTypeGIF; break; case kJPEG_Type: type = kUTTypeJPEG; break; case kPNG_Type: // PNG encoding an ARGB_4444 bitmap gives the following errors in GM: // <Error>: CGImageDestinationAddImage image could not be converted to destination // format. // <Error>: CGImageDestinationFinalize image destination does not have enough images // So instead we copy to 8888. if (bm.colorType() == kARGB_4444_SkColorType) { bm.copyTo(&bitmap8888, kN32_SkColorType); bmPtr = &bitmap8888; } type = kUTTypePNG; break; default: return false; } CGImageDestinationRef dst = SkStreamToImageDestination(stream, type); if (NULL == dst) { return false; } SkAutoTCallVProc<const void, CFRelease> ardst(dst); CGImageRef image = SkCreateCGImageRef(*bmPtr); if (NULL == image) { return false; } SkAutoTCallVProc<CGImage, CGImageRelease> agimage(image); CGImageDestinationAddImage(dst, image, NULL); return CGImageDestinationFinalize(dst); }
static void quartzgen_end_job(GVJ_t *job) { CGContextRef context = (CGContextRef)job->context; if (!job->external_context) { switch (job->device.id) { case FORMAT_PDF: /* save the PDF */ CGPDFContextClose(context); break; case FORMAT_CGIMAGE: break; #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1040 default: /* bitmap formats */ { /* create an image destination */ CGDataConsumerRef data_consumer = CGDataConsumerCreate(job, &device_data_consumer_callbacks); CGImageDestinationRef image_destination = CGImageDestinationCreateWithDataConsumer(data_consumer, format_uti[job->device.id], 1, NULL); /* add the bitmap image to the destination and save it */ CGImageRef image = CGBitmapContextCreateImage(context); CGImageDestinationAddImage(image_destination, image, NULL); CGImageDestinationFinalize(image_destination); /* clean up */ if (image_destination) CFRelease(image_destination); CGImageRelease(image); CGDataConsumerRelease(data_consumer); } break; #endif } CGContextRelease(context); } else if (job->device.id == FORMAT_CGIMAGE) { /* create an image and save it where the window field is, which was set to the passed-in context at begin job */ *((CGImageRef*)job->window) = CGBitmapContextCreateImage(context); #if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 20000 void* context_data = CGBitmapContextGetData(context); size_t context_datalen = CGBitmapContextGetBytesPerRow(context) * CGBitmapContextGetHeight(context); #endif CGContextRelease(context); #if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 20000 munmap(context_data, context_datalen); #endif } }
static void exportCGImageToFileWithDestination(CGImageRef image, CFURLRef url, CFStringRef outputFormat, float dpi) { CFTypeRef keys[2]; CFTypeRef values[2]; CFDictionaryRef options = NULL; // Create an image destination at the supplied URL that // corresponds to the output image format. The destination will // only contain 1 image. CGImageDestinationRef imageDestination = CGImageDestinationCreateWithURL(url, outputFormat, 1, NULL); if(imageDestination == NULL){ fprintf(stderr, "Couldn't create image destination!\n"); return; } // Set the keys to be the x and y resolution of the image. keys[0] = kCGImagePropertyDPIWidth; keys[1] = kCGImagePropertyDPIHeight; // Create a CFNumber for the resolution and use it as the // x and y resolution. values[0] = values[1] = CFNumberCreate(NULL, kCFNumberFloatType, &dpi); // Create an options dictionary with these keys. options = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); // Release the CFNumber the code created. CFRelease(values[0]); // Add the image with the options dictionary to the destination. CGImageDestinationAddImage(imageDestination, image, options); // Release the options dictionary this code created. CFRelease(options); // When all the images are added to the destination, finalize it. CGImageDestinationFinalize(imageDestination); // Release the destination when done with it. CFRelease(imageDestination); }
String ImageBuffer::toDataURL(const String& mimeType, const double* quality) const { ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); RetainPtr<CGImageRef> image; if (!m_accelerateRendering) image.adoptCF(CGBitmapContextCreateImage(context()->platformContext())); #if USE(IOSURFACE_CANVAS_BACKING_STORE) else image.adoptCF(wkIOSurfaceContextCreateImage(context()->platformContext())); #endif if (!image) return "data:,"; RetainPtr<CFMutableDataRef> data(AdoptCF, CFDataCreateMutable(kCFAllocatorDefault, 0)); if (!data) return "data:,"; RetainPtr<CFStringRef> uti = utiFromMIMEType(mimeType); ASSERT(uti); RetainPtr<CGImageDestinationRef> destination(AdoptCF, CGImageDestinationCreateWithData(data.get(), uti.get(), 1, 0)); if (!destination) return "data:,"; RetainPtr<CFDictionaryRef> imageProperties = 0; if (CFEqual(uti.get(), jpegUTI()) && quality && *quality >= 0.0 && *quality <= 1.0) { // Apply the compression quality to the image destination. RetainPtr<CFNumberRef> compressionQuality(AdoptCF, CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, quality)); const void* key = kCGImageDestinationLossyCompressionQuality; const void* value = compressionQuality.get(); imageProperties.adoptCF(CFDictionaryCreate(0, &key, &value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); } CGImageDestinationAddImage(destination.get(), image.get(), imageProperties.get()); CGImageDestinationFinalize(destination.get()); Vector<char> out; base64Encode(reinterpret_cast<const char*>(CFDataGetBytePtr(data.get())), CFDataGetLength(data.get()), out); return makeString("data:", mimeType, ";base64,", out); }
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; }
String ImageBuffer::toDataURL(const String& mimeType) const { ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); RetainPtr<CGImageRef> image(AdoptCF, CGBitmapContextCreateImage(context()->platformContext())); if (!image) return "data:,"; size_t width = CGImageGetWidth(image.get()); size_t height = CGImageGetHeight(image.get()); OwnArrayPtr<uint32_t> imageData(new uint32_t[width * height]); if (!imageData) return "data:,"; RetainPtr<CGImageRef> transformedImage(AdoptCF, CGBitmapContextCreateImage(context()->platformContext())); if (!transformedImage) return "data:,"; RetainPtr<CFMutableDataRef> transformedImageData(AdoptCF, CFDataCreateMutable(kCFAllocatorDefault, 0)); if (!transformedImageData) return "data:,"; RetainPtr<CGImageDestinationRef> imageDestination(AdoptCF, CGImageDestinationCreateWithData(transformedImageData.get(), utiFromMIMEType(mimeType).get(), 1, 0)); if (!imageDestination) return "data:,"; CGImageDestinationAddImage(imageDestination.get(), transformedImage.get(), 0); CGImageDestinationFinalize(imageDestination.get()); Vector<char> in; in.append(CFDataGetBytePtr(transformedImageData.get()), CFDataGetLength(transformedImageData.get())); Vector<char> out; base64Encode(in, out); out.append('\0'); return String::format("data:%s;base64,%s", mimeType.utf8().data(), out.data()); }
void os_image_save_to_file(const char* filename, unsigned char* data, int width, int height, int channels) { assert((channels == 3) || (channels == 4)); const int bytesPerRow = (width * channels); const int bytesPerImage = (bytesPerRow * height); const int bitsPerChannel = 8; const int bitsPerPixel = (bitsPerChannel * channels); CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); CFDataRef rgbData = CFDataCreate(NULL, data, bytesPerImage); CGDataProviderRef provider = CGDataProviderCreateWithCFData(rgbData); CGImageRef imageRef = CGImageCreate( width, height, bitsPerChannel, bitsPerPixel, bytesPerRow, colorspace, kCGBitmapByteOrderDefault, provider, NULL, true, kCGRenderingIntentDefault); CFRelease(rgbData); CGDataProviderRelease(provider); CGColorSpaceRelease(colorspace); CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL, (const uint8_t*)filename, (CFIndex)strlen(filename), false); CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, NULL); CGImageDestinationAddImage(destination, imageRef, nil); if (!CGImageDestinationFinalize(destination)) { fprintf(stderr, "Failed to write image to %s\n", filename); } CFRelease(destination); CFRelease(url); CGImageRelease(imageRef); }
int main(int argc, const char * argv[]) { size_t width = 2000; size_t height = 2000; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(nullptr, width, height, 8, width * 4, colorSpace, kCGImageAlphaNoneSkipLast); CGColorSpaceRelease(colorSpace); const std::vector<uint8_t> fontVector = generateFont(); std::ofstream outputFile("/Volumes/Data/home/mmaxfield/tmp/output.otf", std::ios::out | std::ios::binary); for (uint8_t b : fontVector) outputFile << b; outputFile.close(); CFDataRef fontData = CFDataCreate(kCFAllocatorDefault, fontVector.data(), fontVector.size()); CTFontDescriptorRef fontDescriptor = CTFontManagerCreateFontDescriptorFromData(fontData); CFRelease(fontData); CFTypeRef featureValues[] = { CFSTR("liga"), CFSTR("clig"), CFSTR("dlig"), CFSTR("hlig"), CFSTR("calt"), CFSTR("subs"), CFSTR("sups"), CFSTR("smcp"), CFSTR("c2sc"), CFSTR("pcap"), CFSTR("c2pc"), CFSTR("unic"), CFSTR("titl"), CFSTR("onum"), CFSTR("pnum"), CFSTR("tnum"), CFSTR("frac"), CFSTR("afrc"), CFSTR("ordn"), CFSTR("zero"), CFSTR("hist"), CFSTR("jp78"), CFSTR("jp83"), CFSTR("jp90"), CFSTR("jp04"), CFSTR("smpl"), CFSTR("trad"), CFSTR("fwid"), CFSTR("pwid"), CFSTR("ruby") }; CFArrayRef features = CFArrayCreate(kCFAllocatorDefault, featureValues, 30, &kCFTypeArrayCallBacks); for (CFIndex i = 0; i < CFArrayGetCount(features); ++i) { drawTextWithFeature(context, fontDescriptor, static_cast<CFStringRef>(CFArrayGetValueAtIndex(features, i)), 1, CGPointMake(25, 1950 - 50 * i)); drawTextWithFeature(context, fontDescriptor, static_cast<CFStringRef>(CFArrayGetValueAtIndex(features, i)), 0, CGPointMake(25, 1925 - 50 * i)); } CFRelease(features); CFRelease(fontDescriptor); CGImageRef image = CGBitmapContextCreateImage(context); CGContextRelease(context); CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/Volumes/Data/home/mmaxfield/tmp/output.png"), kCFURLPOSIXPathStyle, FALSE); CGImageDestinationRef imageDestination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, nullptr); CFRelease(url); CGImageDestinationAddImage(imageDestination, image, nullptr); CGImageRelease(image); CGImageDestinationFinalize(imageDestination); CFRelease(imageDestination); return 0; }
static bool CGImageEncodeToData(CGImageRef image, CFStringRef uti, const double* quality, CFMutableDataRef data) { if (!image || !uti || !data) return false; RetainPtr<CGImageDestinationRef> destination = adoptCF(CGImageDestinationCreateWithData(data, uti, 1, 0)); if (!destination) return false; RetainPtr<CFDictionaryRef> imageProperties = 0; if (CFEqual(uti, jpegUTI()) && quality && *quality >= 0.0 && *quality <= 1.0) { // Apply the compression quality to the JPEG image destination. RetainPtr<CFNumberRef> compressionQuality = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, quality)); const void* key = kCGImageDestinationLossyCompressionQuality; const void* value = compressionQuality.get(); imageProperties = adoptCF(CFDictionaryCreate(0, &key, &value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); } // Setting kCGImageDestinationBackgroundColor to black for JPEG images in imageProperties would save some math // in the calling functions, but it doesn't seem to work. CGImageDestinationAddImage(destination.get(), image, imageProperties.get()); return CGImageDestinationFinalize(destination.get()); }
QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, QVariant variant, QString flav) { QList<QByteArray> ret; if (!canConvert(mime, flav)) return ret; QImage img = qvariant_cast<QImage>(variant); QCFType<CGImageRef> cgimage = qt_mac_createCGImageFromQImage(img); #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { QCFType<CFMutableDataRef> data = CFDataCreateMutable(0, 0); QCFType<CGImageDestinationRef> imageDestination = CGImageDestinationCreateWithData(data, kUTTypeTIFF, 1, 0); if (imageDestination != 0) { CFTypeRef keys[2]; QCFType<CFTypeRef> values[2]; QCFType<CFDictionaryRef> options; keys[0] = kCGImagePropertyPixelWidth; keys[1] = kCGImagePropertyPixelHeight; int width = img.width(); int height = img.height(); values[0] = CFNumberCreate(0, kCFNumberIntType, &width); values[1] = CFNumberCreate(0, kCFNumberIntType, &height); options = CFDictionaryCreate(0, reinterpret_cast<const void **>(keys), reinterpret_cast<const void **>(values), 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CGImageDestinationAddImage(imageDestination, cgimage, options); CGImageDestinationFinalize(imageDestination); } QByteArray ar(CFDataGetLength(data), 0); CFDataGetBytes(data, CFRangeMake(0, ar.size()), reinterpret_cast<UInt8 *>(ar.data())); ret.append(ar); } else #endif { #ifdef Q_WS_MAC32 Handle tiff = NewHandle(0); if (resolveMimeQuickTimeSymbols()) { GraphicsExportComponent graphicsExporter; ComponentResult result = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypeTIFF, &graphicsExporter); if (!result) { unsigned long sizeWritten; result = ptrGraphicsExportSetInputCGImage(graphicsExporter, cgimage); if (!result) result = ptrGraphicsExportSetOutputHandle(graphicsExporter, tiff); if (!result) result = ptrGraphicsExportDoExport(graphicsExporter, &sizeWritten); CloseComponent(graphicsExporter); } } int size = GetHandleSize((Handle)tiff); QByteArray ar(reinterpret_cast<char *>(*tiff), size); ret.append(ar); DisposeHandle(tiff); #endif } return ret; }
// save the image void save_image (vImage_Buffer *src_i, img_prop o, float compression, char *o_file) { // Create a CFDataRef from the rotated data in the destination vImage_Buffer CFDataRef output_Data = CFDataCreate (NULL, src_i->data, src_i->height * src_i->rowBytes); if (o->bits_ppixel == 32) { // convert from 24bit to 32bit by adding the alpha channel. output_Data = convert32_24bit (output_Data, o); src_i->rowBytes = src_i->width * 3; } // Check for a NULL value. if (NULL == output_Data) { printf ("Could not create CFDataRef from vImage_Buffer.\n"); exit (0); } // Create a Data provider from the rotated data CGDataProviderRef destination_data_provider = CGDataProviderCreateWithCFData (output_Data); // Check for null if (NULL == destination_data_provider) { printf ("Could not create CGDataProviderRef from CGDataRef.\n"); exit (0); } CGImageRef processed_image; // Create the image with sRGB for the colour space processed_image = CGImageCreate (src_i->width, // 1 width src_i->height, // 2 height (size_t)o->bits_ppixel/ (o->bits_ppixel/8), // bitsPerComponent (size_t)o->bits_ppixel, //bitsPerPixel src_i->rowBytes, // bytesPerRow CGColorSpaceCreateDeviceRGB(), // Generic ColourSpace kCGBitmapByteOrder32Big, // bitmapInfo destination_data_provider, // Data provider ** DataProviderRef NULL, // decode 0, // Interpolate kCGRenderingIntentSaturation); // rendering intent if (NULL == processed_image) exit (0); /* } else { // release the reference colour space CGColorSpaceRelease(rgb); // Create the image with sRGB for the colour space processed_image = CGImageCreate (src_i->width, // 1 width src_i->height, // 2 height (size_t)o->bits_ppixel/ (o->bits_ppixel/8), // bitsPerComponent (size_t)o->bits_ppixel, //bitsPerPixel src_i->rowBytes, // bytesPerRow o->colorSpace, // ColourSpace of original kCGBitmapByteOrder32Big, // bitmapInfo destination_data_provider, // Data provider ** DataProviderRef NULL, // decode 0, // Interpolate kCGRenderingIntentSaturation); // rendering intent if (NULL == processed_image) exit (0); }*/ // create a CFStringRef from the C string CFStringRef fn = CFStringCreateWithCString (NULL, o_file, kCFStringEncodingUTF8); if (NULL == fn) exit (0); // Convert the CFStringRef to a CFURLRef CFURLRef fon = CFURLCreateWithFileSystemPath (NULL, fn, kCFURLPOSIXPathStyle, false); if (NULL == fon) exit (0); // Create an image destination CGImageDestinationRef image_destination = CGImageDestinationCreateWithURL (fon, kUTTypeJPEG, 1, NULL); // Release the CFURLRef CFRelease (fon); fon = NULL; // release the CFStringRef CFRelease (fn); fn = NULL; // Check for a NULL value in image_destination if (NULL == image_destination) { printf ("Null Image_destination: Could not create the CGImageDestinationRef from the supplied URL.\n"); exit (0); } // Set the compression factor for the images CFStringRef keys[1]; CFTypeRef value[1]; // Use compression key keys[0] = kCGImageDestinationLossyCompressionQuality; // set the compression amount. 1 = no compression 0 = max compression value[0] = CFNumberCreate (NULL, kCFNumberFloatType, &compression); // Pointer to the image attribs dictionary CFDictionaryRef options; // create the dictionary options = CFDictionaryCreate (kCFAllocatorDefault, (void *)keys, (void *)value, 1, NULL, NULL); // Copy data to the output information to the destination CGImageDestinationAddImage (image_destination, processed_image, options); // Check for a NULL value in image_destination if (NULL == image_destination) { printf ("Null Image_destination: Could not add the rotated image.\n"); exit (0); } // Write the image to disk if (!CGImageDestinationFinalize (image_destination)) { // Could not write the file for some reason printf ("Could not write the file to disk.\n"); exit (1); } // Release the pointer the the scaled buffer CFRelease (output_Data); output_Data = NULL; // Release the dictionary CFRelease (keys[0]); CFRelease (value[0]); CFRelease (options); options = NULL; // Release the rotated image. CGImageRelease (processed_image); processed_image = NULL; // Release a data provider CGDataProviderRelease (destination_data_provider); destination_data_provider = NULL; // Release the image destination CFRelease (image_destination); image_destination = NULL; } // save_image
/* write image file */ int BIWriteFile( const char *fileName, BIFileType fileType, const BIImageInfo *imageInfo, const unsigned char *bitmap) { int ourRtn = 0; CGImageAlphaInfo alpha; CGBitmapInfo bitmapInfo = 0; CGContextRef bitmapContextRef = NULL; CGImageRef imageRef = NULL; CFURLRef fileURL = NULL; CGImageDestinationRef imageDestRef = NULL; CGColorSpaceRef rgbColorSpaceRef = NULL; CFStringRef uti = NULL; CFDictionaryRef propDict = NULL; if(imageInfo->bitsPerPixel == 8) { /* grayscale image */ rgbColorSpaceRef = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); alpha = kCGImageAlphaNone; bitmapInfo = 0; } else { /* RGB no alpha */ rgbColorSpaceRef = CGColorSpaceCreateDeviceRGB(); alpha = kCGImageAlphaNoneSkipLast; bitmapInfo = kCGBitmapByteOrder32Big | alpha; } if(rgbColorSpaceRef == NULL) { fprintf(stderr, "***BIWriteFile: Error on CGColorSpaceCreateWithName\n"); ourRtn = 1; goto errOut; } /* A bitmap-oriented CGContextRef based on bitmap data */ bitmapContextRef = CGBitmapContextCreate((void *)bitmap, imageInfo->imageWidth, imageInfo->imageHeight, imageInfo->bitsPerComponent, imageInfo->bytesPerRow, rgbColorSpaceRef, bitmapInfo); if(bitmapContextRef == NULL) { fprintf(stderr, "***BIWriteFile: Error creating CGBitmapContext\n"); ourRtn = 1; goto errOut; } /* CGContextRef --> CGImageRef */ imageRef = CGBitmapContextCreateImage(bitmapContextRef); fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (unsigned char*)fileName, strlen(fileName), FALSE); if(fileURL == NULL) { fprintf(stderr, "***BIWriteFile: Error on CFURLCreateFromFileSystemRepresentation\n"); ourRtn = 1; goto errOut; } uti = BIGetUTI(fileURL, fileType); if(uti == NULL) { ourRtn = 1; goto errOut; } imageDestRef = CGImageDestinationCreateWithURL(fileURL, uti, 1, NULL ); if(imageDestRef == NULL) { fprintf(stderr, "***BIWriteFile: Error on CGImageDestinationCreateWithURL\n"); ourRtn = 1; goto errOut; } /* Some BIFileTypes require the specification of a "Lossless" property */ switch(fileType) { case BI_FT_JPEG2000_Lossless: case BI_FT_JPEG_Lossless: { CFStringRef key = kCGImageDestinationLossyCompressionQuality; float valf = 1.0; CFNumberRef val = CFNumberCreate(NULL, kCFNumberFloatType, &valf); propDict = CFDictionaryCreate(NULL, (const void **)&key, (const void **)&val, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); /* * The docs say we should be able to set these properties like this, * but that has no effect. We need to pass it as the 'properties' argument * to CGImageDestinationAddImage(), below. * See <rdar://problem/5670614> */ //CGImageDestinationSetProperties(imageDestRef, propDict); CFRelease(val); break; } default: break; } CGImageDestinationAddImage(imageDestRef, imageRef, propDict); /* Write the image to disk */ if(!CGImageDestinationFinalize(imageDestRef)) { fprintf(stderr, "***BIWriteFile: Error on CGImageDestinationFinalize\n"); ourRtn = 1; } if(propDict != NULL) { CFRelease(propDict); } errOut: CFRELEASE(bitmapContextRef); CFRELEASE(imageRef); CFRELEASE(fileURL); CFRELEASE(imageDestRef); CFRELEASE(rgbColorSpaceRef); return ourRtn; }
bool ImageIOEncoder::write( const Mat& img, const vector<int>& params ) { int width = img.cols, height = img.rows; int _channels = img.channels(); const uchar* data = img.data; int step = img.step; // Determine the appropriate UTI based on the filename extension CFStringRef imageUTI = FilenameToUTI( m_filename.c_str() ); // Determine the Bytes Per Pixel int bpp = (_channels == 1) ? 1 : 4; // Write the data into a bitmap context CGContextRef context; CGColorSpaceRef colorSpace; uchar* bitmapData = NULL; if( bpp == 1 ) colorSpace = CGColorSpaceCreateWithName( kCGColorSpaceGenericGray ); else if( bpp == 4 ) colorSpace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGBLinear ); if( !colorSpace ) return false; bitmapData = (uchar*)malloc( bpp * height * width ); if( !bitmapData ) { CGColorSpaceRelease( colorSpace ); return false; } context = CGBitmapContextCreate( bitmapData, width, height, 8, bpp * width, colorSpace, (bpp == 1) ? kCGImageAlphaNone : kCGImageAlphaNoneSkipLast ); CGColorSpaceRelease( colorSpace ); if( !context ) { free( bitmapData ); return false; } // Copy pixel information from data into bitmapData if (bpp == 4) { int bitmapIndex = 0; const uchar * base = data; for (int y = 0; y < height; y++) { const uchar * line = base + y * step; for (int x = 0; x < width; x++) { // Blue channel bitmapData[bitmapIndex + 2] = line[0]; // Green channel bitmapData[bitmapIndex + 1] = line[1]; // Red channel bitmapData[bitmapIndex + 0] = line[2]; line += 3; bitmapIndex += bpp; } } } else if (bpp == 1) { for (int y = 0; y < height; y++) memcpy (bitmapData + y * width, data + y * step, width); } // Turn the bitmap context into an imageRef CGImageRef imageRef = CGBitmapContextCreateImage( context ); CGContextRelease( context ); if( !imageRef ) { free( bitmapData ); return false; } // Write the imageRef to a file based on the UTI CFURLRef imageURLRef = CFURLCreateFromFileSystemRepresentation( NULL, (const UInt8*)m_filename.c_str(), m_filename.size(), false ); if( !imageURLRef ) { CGImageRelease( imageRef ); free( bitmapData ); return false; } CGImageDestinationRef destRef = CGImageDestinationCreateWithURL( imageURLRef, imageUTI, 1, NULL); CFRelease( imageURLRef ); if( !destRef ) { CGImageRelease( imageRef ); free( bitmapData ); fprintf(stderr, "!destRef\n"); return false; } CGImageDestinationAddImage(destRef, imageRef, NULL); if( !CGImageDestinationFinalize(destRef) ) { fprintf(stderr, "Finalize failed\n"); return false; } CFRelease( destRef ); CGImageRelease( imageRef ); free( bitmapData ); return true; }