Немного подробнее ...
Я отправил ранее этим вечером с консолидацией и небольшим дополнением к тому, что было сказано на этой странице - это можно найти внизу этого поста. На данный момент я редактирую сообщение, однако, чтобы опубликовать то, что я предлагаю, - это (по крайней мере, для моих требований, которые включают изменение данных пикселей) лучший метод, так как он предоставляет доступные для записи данные (тогда как, как я понимаю, предоставленный метод по предыдущим постам и в нижней части этого поста предоставлена только для чтения ссылка на данные).
Способ 1: записываемая информация о пикселях
Я определил константы
#define RGBA 4
#define RGBA_8_BIT 8
В моем подклассе UIImage я объявил переменные экземпляра:
size_t bytesPerRow;
size_t byteCount;
size_t pixelCount;
CGContextRef context;
CGColorSpaceRef colorSpace;
UInt8 *pixelByteData;
// A pointer to an array of RGBA bytes in memory
RPVW_RGBAPixel *pixelData;
Структура пикселя (с альфа-каналом в этой версии)
typedef struct RGBAPixel {
byte red;
byte green;
byte blue;
byte alpha;
} RGBAPixel;
Функция растрового изображения (возвращает предварительно рассчитанный RGBA; разделите RGB на A, чтобы получить неизмененный RGB):
-(RGBAPixel*) bitmap {
NSLog( @"Returning bitmap representation of UIImage." );
// 8 bits each of red, green, blue, and alpha.
[self setBytesPerRow:self.size.width * RGBA];
[self setByteCount:bytesPerRow * self.size.height];
[self setPixelCount:self.size.width * self.size.height];
// Create RGB color space
[self setColorSpace:CGColorSpaceCreateDeviceRGB()];
if (!colorSpace)
{
NSLog(@"Error allocating color space.");
return nil;
}
[self setPixelData:malloc(byteCount)];
if (!pixelData)
{
NSLog(@"Error allocating bitmap memory. Releasing color space.");
CGColorSpaceRelease(colorSpace);
return nil;
}
// Create the bitmap context.
// Pre-multiplied RGBA, 8-bits per component.
// The source image format will be converted to the format specified here by CGBitmapContextCreate.
[self setContext:CGBitmapContextCreate(
(void*)pixelData,
self.size.width,
self.size.height,
RGBA_8_BIT,
bytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast
)];
// Make sure we have our context
if (!context) {
free(pixelData);
NSLog(@"Context not created!");
}
// Draw the image to the bitmap context.
// The memory allocated for the context for rendering will then contain the raw image pixelData in the specified color space.
CGRect rect = { { 0 , 0 }, { self.size.width, self.size.height } };
CGContextDrawImage( context, rect, self.CGImage );
// Now we can get a pointer to the image pixelData associated with the bitmap context.
pixelData = (RGBAPixel*) CGBitmapContextGetData(context);
return pixelData;
}
Данные только для чтения (Предыдущая информация) - метод 2:
Шаг 1. Я объявил тип для байта:
typedef unsigned char byte;
Шаг 2. Я объявил структуру, соответствующую пикселю:
typedef struct RGBPixel{
byte red;
byte green;
byte blue;
}
RGBPixel;
Шаг 3. Я создал подкласс UIImageView и объявил (с соответствующими синтезированными свойствами):
// Reference to Quartz CGImage for receiver (self)
CFDataRef bitmapData;
// Buffer holding raw pixel data copied from Quartz CGImage held in receiver (self)
UInt8* pixelByteData;
// A pointer to the first pixel element in an array
RGBPixel* pixelData;
Шаг 4. Код подкласса Я вставил метод с именем bitmap (чтобы вернуть данные пикселей растрового изображения):
//Get the bitmap data from the receiver's CGImage (see UIImage docs)
[self setBitmapData: CGDataProviderCopyData(CGImageGetDataProvider([self CGImage]))];
//Create a buffer to store bitmap data (unitialized memory as long as the data)
[self setPixelBitData:malloc(CFDataGetLength(bitmapData))];
//Copy image data into allocated buffer
CFDataGetBytes(bitmapData,CFRangeMake(0,CFDataGetLength(bitmapData)),pixelByteData);
//Cast a pointer to the first element of pixelByteData
//Essentially what we're doing is making a second pointer that divides the byteData's units differently - instead of dividing each unit as 1 byte we will divide each unit as 3 bytes (1 pixel).
pixelData = (RGBPixel*) pixelByteData;
//Now you can access pixels by index: pixelData[ index ]
NSLog(@"Pixel data one red (%i), green (%i), blue (%i).", pixelData[0].red, pixelData[0].green, pixelData[0].blue);
//You can determine the desired index by multiplying row * column.
return pixelData;
Шаг 5. Я сделал метод доступа:
-(RGBPixel*)pixelDataForRow:(int)row column:(int)column{
//Return a pointer to the pixel data
return &pixelData[row * column];
}