Получение пиксельных данных от объекта CGImage
Q: Как делают я получаю доступ к пиксельным данным a CGImage объект?
A: Как делают я получаю доступ к пиксельным данным a CGImage объект?
На Mac OS X 10.5 или позже, новый вызов был добавлен, который позволяет Вам получать данные фактического пикселя из a CGImage объект. Этот вызов, CGDataProviderCopyData, возвращает объект CFData, содержащий пиксельные данные от рассматриваемого изображения. Пример использования этого вызова для получения пиксельных данных из a CGImage показан в Перечислении 1. Как только у Вас есть объект CFData с Вашей информацией о пикселе, можно вызвать CFDataGetBytePtr получить указатель на пиксельные данные, или CFDataGetBytes скопировать поддиапазон пиксельных данных.
Перечисление 1 , Получающее данные необработанного пикселя от a CGImage.
CFDataRef CopyImagePixels(CGImageRef inImage) { return CGDataProviderCopyData(CGImageGetDataProvider(inImage)); } |
До Mac OS X 10.5 пиксели изображения не так легко доступны. Единственный способ гарантировать доступ к эквивалентным битам состоит в том, чтобы создать растровый контекст с буфером памяти, который Вы указываете и затем рисуете CGImage к использованию контекста CGContextDrawImage. После рисования CGImage к контексту у Вас будет копия данных в буфере, который Вы указали (к которому можно также легко получить доступ с помощью CGBitmapContexGetData функция). Код в Перечислении 2 демонстрирует, как сделать это.
Для получения дополнительной информации о создании растровых контекстов для других форматов пикселя, посмотрите Кварц 2D Руководство по программированию.
Перечисление 2 , Получающее доступ к пиксельным данным a CGImage.
void ManipulateImagePixelData(CGImageRef inImage)
{
// Create the bitmap context
CGContextRef cgctx = CreateARGBBitmapContext(inImage);
if (cgctx == NULL)
{
// error creating context
return;
}
// Get image width, height. We'll use the entire image.
size_t w = CGImageGetWidth(inImage);
size_t h = CGImageGetHeight(inImage);
CGRect rect = {{0,0},{w,h}};
// 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(cgctx, rect, inImage);
// Now we can get a pointer to the image data associated with the bitmap
// context.
void *data = CGBitmapContextGetData (cgctx);
if (data != NULL)
{
// **** You have a pointer to the image data ****
// **** Do stuff with the data here ****
}
// When finished, release the context
CGContextRelease(cgctx);
// Free image data memory for the context
if (data)
{
free(data);
}
}
CGContextRef CreateARGBBitmapContext (CGImageRef inImage)
{
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
// Get image width, height. We'll use the entire image.
size_t pixelsWide = CGImageGetWidth(inImage);
size_t pixelsHigh = CGImageGetHeight(inImage);
// 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);
if (colorSpace == NULL)
{
fprintf(stderr, "Error allocating color space\n");
return NULL;
}
// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
bitmapData = malloc( bitmapByteCount );
if (bitmapData == NULL)
{
fprintf (stderr, "Memory not allocated!");
CGColorSpaceRelease( colorSpace );
return NULL;
}
// 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);
if (context == NULL)
{
free (bitmapData);
fprintf (stderr, "Context not created!");
}
// Make sure and release colorspace before returning
CGColorSpaceRelease( colorSpace );
return context;
} |
Ссылки
История версии документа
| Дата | Примечания |
|---|---|
| 27.08.2008 | Обновленный для обращения к CGDataProviderCopyData (), доступный с Mac OS X 10.5. |
| 05.03.2007 | Новый документ, описывающий, как получить доступ к пиксельным данным объекта CGImage |