У меня есть несколько изображений PNG с альфа-прозрачностью. Они отображаются правильно при использовании для общих вещей Quartz, таких как пользовательский интерфейс. Однако, когда я беру изображение и загружаю его в OpenGL, я обнаруживаю, что получаемые мной данные имеют твердую альфа 255. Я использую то, что кажется обычным преобразованием UIImage в CGImage и рендерингом в контексте. Я размещу соответствующие фрагменты кода ниже.
Я провел много поисков и, наконец, наткнулся на способ обойти это, и я хотел поделиться здесь, но он медленный, поскольку он должен перебирать каждый пиксель и копировать эту необработанную альфа-канал в альфа-канал. Я хотел бы знать способ обойти это. Я не переключал никакие параметры PNG в своей сборке (не уверен, где это установить), чтобы посмотреть, поможет ли это ..
Благодарность
Сначала я получаю UIImage из своего приложения, которое я добавил вот так:
UIImage *image = [UIImage imageNamed:imageName];
затем я конвертирую в CGImageRef и создаю обычный контекст, как только эта соответствующая строка:
CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height,
bitsPerComponent, bytesPerRow,
CGImageGetColorSpace(spriteImage),
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
Затем эти следующие две строки - это волшебство, чтобы получить меня к НАСТОЯЩИМ необработанным данным png ... Я, вероятно, должен проверить RGBA по сравнению с другими форматами, но я ленив ... После этого я рисую изображение, а затем возвращаюсь и исправляю альфа ... да Я знаю, что могу сделать это за один цикл и пропуская байты, это сейчас более читабельно ...
// THIS data actually HAS the alpha!!
CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(spriteImage));
GLubyte *pixels = (GLubyte *)CFDataGetBytePtr(data);
// 3
CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage);
// Sadly we now have to loop and fix the ALPHA directly from the raw PNG source
// data as otherwise we get wrong/missing alpha...
for (int y=0; y < height; ++y) {
for (int x=0; x < width; ++x) {
int byteIndex = (bytesPerRow * y) + (x * bytesPerPixel);
spriteData[byteIndex + 3] = pixels[byteIndex +3 ];
}
}
затем я выполняю обычные вызовы glTexture и т. д., и все работает нормально .. Если я пропущу цикл копирования выше, я получаю спрайты без альфы. Если я сделаю это выше, мои спрайты будут правильно рисоваться с прозрачностью.
Я знаю обо всем, что делает iOS до умножения, но это кажется сломанным ... По крайней мере, надеюсь, что вышесказанное может кому-то помочь, но должен быть способ получше ???
Мысли? Спасибо!