Значения iPhone RGBA не сохранены правильно - PullRequest
0 голосов
/ 21 декабря 2011

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

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

Ответы [ 2 ]

3 голосов
/ 21 декабря 2011

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

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

CGFloat red = copyPixels[i+2] * 255.0f / copyPixels[i];
1 голос
/ 21 декабря 2011

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

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

...