прозрачность / альфа в контексте CoreGraphics (iphone, objc) - PullRequest
1 голос
/ 01 сентября 2010

В настоящее время я делаю основной редактор изображений для iphone.

Я беру CGImageRef из UIImage и создаю для него контекст, используя следующий код

origImage = result.CGImage;

Iheight = CGImageGetHeight(origImage);
Iwidth = CGImageGetWidth(origImage);
IcolorSpace = CGColorSpaceCreateDeviceRGB();
IrawData = malloc(Iheight * Iwidth * 4);
IbytesPerPixel = 4;
IbytesPerRow = IbytesPerPixel * Iwidth;
IbitsPerComponent = 8;
Icontext = CGBitmapContextCreate(IrawData, Iwidth, Iheight, IbitsPerComponent,
                                 IbytesPerRow, IcolorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big
                                 );
//[bytesPerRow release];
CGContextSetBlendMode(Icontext, kCGBlendModeCopy);
CGContextDrawImage(Icontext, CGRectMake(0,0,Iwidth,Iheight),  origImage);

Затем я перебираю пиксели

for (int x=0; x<Iwidth; x++) {
    for (int y=0; y<Iheight; y++) {
            //and  set the alpha component to 0
            int byteIndex = (y*IbytesPerRow) + x*IbytesPerPixel;

            IrawData[byteIndex+3] = 0;

            }
}

, а затем создаю CGImageRef из контекста с помощью

    CGImageRef imagea = CGBitmapContextCreateImage(Icontext);

, добавляю CGImage в UIImage и присваиваем UIImageView

Проблема в том, что изменение альфа не влияет на результирующее изображение

, если я изменяю цвет пикселей с помощью

IrawData[byteIndex+(0/1/2)]

, цвет меняется,но Я все еще не могу изменить альфа пикселя

Спасибо,

nonono

1 Ответ

5 голосов
/ 01 сентября 2010

Не забудьте предварительно умножить цвета перед изменением альфа-канала и повторно умножить их потом.

Предварительно умноженный цвет (часто называемый «предварительно умноженная альфа», который вводит в заблуждение) означает, что компоненты цвета сохраняются уже умноженными на альфа, чтобы облегчить наложение. Обычная операция компоновки (источник поверх) выглядит так:

result = (source.rgb * source.a) + (destination.rgb * (1.0 - destination.a));

Предварительное умножение означает, что первое умножение уже выполнено, поэтому его можно пропустить:

result =  source.rgb             + (destination.rgb * (1.0 - destination.a));

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

Таким образом, вам необходимо предварительно умножить цвета, то есть разделить каждый из них на альфа (как это было ранее умножено, так что теперь вы должны сделать обратное), прежде чем изменять альфа. Затем, после изменения альфы, предварительно умножьте цвета на новую альфа.

Конечно, это означает, что при изменении альфа на ноль все цвета станут черными (r = g = b = 0). Поэтому убедитесь, что вы сохранили исходное изображение, если пользователь может захотеть изменить его обратно.

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

...