2011-12-21 2 views
0

Я использую GraphicsContext для рисования 2d. Для некоторых операций мне нужно отредактировать отдельные пиксели. Однако что-то странное происходит, мои пиксели не сохраняются, как должны. Я рисую красный прямоугольник, наполовину прозрачный - красный установлен на 1 (255) и прозрачность до 0,5 (128). Когда я читаю пиксели позже - красный теперь 128 (половина его значения), а альфа - 128 (что верно). Я хочу позже найти все красные пиксели со значением 255 и изменить их, но это невозможно, так как они не сохраняют заданное значение. Вот мой код:Значения iPhone RGBA не сохраняются правильно

UIGraphicsBeginImageContextWithOptions(CGSizeMake(widthT, heightT), NO, 1); 
CGContextRef contextRef = UIGraphicsGetCurrentContext(); 
//CGContextSaveGState(contextRef); 
CGContextSetRGBFillColor(contextRef, 1, 0, 0, 0.5); 
CGContextSetRGBStrokeColor(contextRef, 1, 0, 0, 0.5); 
CGContextFillRect(contextRef, CGRectMake(0, 0, 400, 400)); 

UIImage *imageMoonMask = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
//NSData *data = (NSData *)CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage)); 

NSData *data = (NSData *)CGDataProviderCopyData(CGImageGetDataProvider(imageMoonMask.CGImage)); 

Byte *copyPixels = (Byte *)[data bytes]; 
pixels = (Byte *) malloc([data length] * sizeof (Byte)); 

for(int i = 0; i < [data length]; i += 4) { 
    pixels[i] = copyPixels[i]; 
    pixels[i+1] = copyPixels[i+1]; 
    pixels[i+2] = copyPixels[i+2]; //red color 
    pixels[i+3] = copyPixels[i+3]; //alpha 
    NSLog(@"Originalni"); 
    NSLog(@"%u", pixels[i]); 
    NSLog(@"%u", pixels[i+1]); 
    NSLog(@"%u", pixels[i+2]); 
    NSLog(@"%u", pixels[i+3]); 
} 
+1

Похож на то, что ваша альфа-функция предварительно умножается, когда она отображается на изображении (хотя я не знаю почему). Вы можете поэкспериментировать с 'CGContextBeginTransparencyLayer' для рисования альфа-смешанного контента, но я бы предположил, что ваш код будет работать :( – deanWombourne

ответ

3

Байт хранятся в формате альфа предварительно умноженного, чтобы обеспечить более эффективный альфа-смешивание. Вы могли бы избежать премультиплексированной альфы, создав собственный контекст растрового изображения через Core Graphics, например. CGBitmapContextCreate и использовать kCGImageAlphaLast вместо kCGImageAlphaPremultipliedLast ...

Но это может быть проще, чтобы восстановить исходное значение только с помощью

CGFloat red = copyPixels[i+2] * 255.0f/copyPixels[i]; 
+0

Итак, если я создаю изображение через CGBitmapContextCreate и устанавливаю эту константу, пиксели должны храниться в формате без предварительного умножения? – MegaManX

+0

@ MegaManX: Да. – kennytm

1

Если вы хотите, чтобы ваши пиксельные значения RGB должны быть сохранены при использовании альфа предварительно умноженного format bitmap, эти значения должны быть меньше или равно альфа-значению.

Поскольку ваши значения битового массива RGB являются байтовыми целыми числами, попытка перемасштабировать предварительно умноженные значения обратно к непремультиплексному исходному значению будет убывать из-за округления или квантования.

Смежные вопросы