调整图像大小 - Cocoa - MAC OS X

3

我正在尝试编写一个小型库,用于捕获屏幕截图并将图像存储在磁盘上。

我已经成功实现了屏幕截图和图像存储在磁盘上的功能。但是,我无法根据指定的高度和宽度调整图像大小。以下是代码片段:

int imageWidth = 200;
int imageHeight = 200;

CFStringRef keys[2];
CFTypeRef   values[2];
keys[0]   = kCGImagePropertyDPIHeight;
values[0] = CFNumberCreate(NULL, kCFNumberIntType, &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");

如果我做错了什么,请告诉我。

3个回答

3

不确定,没有看到您如何创建CGImageRef,可能会有很多问题。很难看到问题所在。 您尝试使用NSImage吗?它非常易于使用。

NSImage * img = [[NSImage alloc] initWithCGImage:imageRef size:NSZeroSize];
[img setSize: NSMakeSize(imageWidth,imageHeight)];

//do something with img;
[img release];

如果以上方法不行,您可以设置一些断点,并确保您认为有效的所有内容都是真实有效的。

1

这个可以完成我的工作,但不确定它是否高效。

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 );

1

我认为kCGImagePropertyDPIWidthkCGImagePropertyDPIHeight不是CGImageDestinationAddImage的有意义选项。您需要创建一个给定大小的新图像,并将其写入目标。

这可以通过多种方式完成,但最简单的方法可能是通过Grady建议的NSImage进行。您还可以创建所需大小和像素格式的新CGBitmapContext,使用CGContextDrawImage将现有图像绘制到其中,然后使用CGBitmapContextCreateImage提取新的CGImageRef。这有点繁琐,但应该能够帮助您达到目标。


关于这些属性,你是正确的,你可以轮询它们,但CGImageDestinationAddImage只能读取目标属性,这些属性包括“const CFStringRef kCGImageDestinationLossyCompressionQuality”和“const CFStringRef kCGImageDestinationBackgroundColor”。 - Grady Player

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接