I am trying to write a small library that captures the screen shot and stores the image on the disk.
I was able to get the screen shot working and also to get the image stored on a disk. Now, I am not able to resize the image based on the specified height and width. Here is the code snippet:
int imageWidth = 200;
int imageHeight = 200;
CFStringRef keys[2];
CFTypeRef values[2];
keys[0] = kCGImagePropertyDPIHeight;
values[0] = CFNumberCreate(NULL, kCFNumber开发者_开发百科IntType, &imageHeight);
keys[1] = kCGImagePropertyDPIWidth;
values[1] = CFNumberCreate(NULL, kCFNumberIntType, &imageWidth);
CFDictionaryRef options = NULL;
options = CFDictionaryCreate( NULL, (const void **)keys, (const void **)values, 2,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
// Set the image in the image destination to be `image' with
// optional properties specified in saved properties dict.
CGImageDestinationAddImage(dest, imageRef, options);
bool success = CGImageDestinationFinalize(dest);
NSAssert( success != 0, @"Image could not be written successfully");
Please let me know if I am doing something wrong.
not sure, there could be a lot of things going on without seeing how you are making the CGImageRef, it would be tough to see a problem. have you tried to use an NSImage, which is super easy to work with.
NSImage * img = [[NSImage alloc] initWithCGImage:imageRef size:NSZeroSize];
[img setSize: NSMakeSize(imageWidth,imageHeight)];
//do something with img;
[img release];
Failing that you could set some breakpoints, and make sure everything that you think is valid, really is.
I don't think kCGImagePropertyDPIWidth
and kCGImagePropertyDPIHeight
are meaningful options for CGImageDestinationAddImage
. You need to create a new image with the given size and write that to the destination.
This can be done in several ways, but the simplest is probably going via NSImage
as Grady suggests. You could also create a new CGBitmapContext
of the desired size and pixel format, draw the existing image into it with CGContextDrawImage
, then extract a new CGImageRef
with CGBitmapContextCreateImage
. It's a bit tedious, but should get you where you want to go.
This is doing my work, not sure whether this is efficient.
int imageWidth = 200;
int imageHeight = 200;
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
// Get image width, height. We'll use the entire image.
size_t pixelsWide = imageWidth;//CGImageGetWidth(imageRef);
size_t pixelsHigh = imageHeight;//CGImageGetHeight(imageRef);
// Declare the number of bytes per row. Each pixel in the bitmap in this
// example is represented by 4 bytes; 8 bits each of red, green, blue, and
// alpha.
bitmapBytesPerRow = (pixelsWide * 4);
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
// Use the generic RGB color space.
colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
bitmapData = malloc( bitmapByteCount );
// Create the bitmap context. We want pre-multiplied ARGB, 8-bits
// per component. Regardless of what the source image format is
// (CMYK, Grayscale, and so on) it will be converted over to the format
// specified here by CGBitmapContextCreate.
context = CGBitmapContextCreate (bitmapData,
pixelsWide,
pixelsHigh,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedFirst);
// Make sure and release colorspace before returning
CGColorSpaceRelease( colorSpace );
// Get image width, height. We'll use the entire image.
size_t w = CGImageGetWidth(imageRef);
size_t h = CGImageGetHeight(imageRef);
CGRect rect = {{0,0},{imageWidth,imageHeight}};
// Draw the image to the bitmap context. Once we draw, the memory
// allocated for the context for rendering will then contain the
// raw image data in the specified color space.
CGContextDrawImage(context, rect, imageRef);
CGImageRef outImageRef = NULL;
outImageRef = CGBitmapContextCreateImage( context );
精彩评论