Проблема преобразования цвета EAGLView в UIImage - PullRequest
12 голосов
/ 17 августа 2011

У меня есть EAGLView (взятый из примеров Apple), который я могу успешно преобразовать в UIImage, используя этот код:

- (UIImage *)glToUIImage:(CGSize)size {

NSInteger backingWidth = size.width;
NSInteger backingHeight = size.height;

NSInteger myDataLength = backingWidth * backingHeight * 4;

// allocate array and read pixels into it.
GLuint *buffer = (GLuint *) malloc(myDataLength);
glReadPixels(0, 0, backingWidth, backingHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

// gl renders “upside down” so swap top to bottom into new array.
for(int y = 0; y < backingHeight / 2; y++) {
    for(int x = 0; x < backingWidth; x++) {
        //Swap top and bottom bytes
        GLuint top = buffer[y * backingWidth + x];
        GLuint bottom = buffer[(backingHeight - 1 - y) * backingWidth + x];
        buffer[(backingHeight - 1 - y) * backingWidth + x] = top;
        buffer[y * backingWidth + x] = bottom;
    }
}

// make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, myDataLength, releaseScreenshotData);

// prep the ingredients
const int bitsPerComponent = 8;
const int bitsPerPixel = 4 * bitsPerComponent;
const int bytesPerRow = 4 * backingWidth;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

// make the cgimage
CGImageRef imageRef = CGImageCreate(backingWidth, backingHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, YES, renderingIntent);
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(provider);

// then make the UIImage from that
UIImage *myImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);

return myImage;

}

void releaseScreenshotData(void *info, const void *data, size_t size) {
free((void *)data);
};

А вот код, в котором я использую этот метод для преобразования в UIImage:

EAGLView *newView = [[EAGLView alloc] initWithImage:photo.originalImage];

[newView reshapeFramebuffer];
[newView drawView:theSlider.tag value:theSlider.value];
//the two lines above are how EAGLViews in Apple's examples are modified


photoItem *newPhoto = [[photoItem alloc] initWithImage:[self glToUIImage:photo.originalImage.size]];

Проблема, с которой я столкнулся, заключается в том, что иногда преобразованный UIImage не будет иметь те же цвета, что и EAGLView. Это происходит, если я применяю высокую насыщенность к EAGLView, или высокую яркость, или низкую контрастность, и некоторые другие случаи. Например, если я применю высокую насыщенность к EAGLView, а затем преобразую в UIImage, некоторые части изображения будут ярче, чем это должно быть.

Итак, я обнаружил, что проблема была скрытой проблемой синхронизации EAGLView, аналогичной моему предыдущему вопросу здесь ( Вопрос синхронизации EAGLView to UIImage ).

1 Ответ

0 голосов
/ 04 ноября 2011

Для тех, кто все еще заботится, смотрите мой комментарий ниже:

Томми, я наконец взломал свой путь к решению.Это была еще одна проблема с синхронизацией EAGLView (которая обнаружилась только во время Насыщения), и я смог ее исправить с помощью подхода executeSelector: afterDelay: 0.0.Thx

Кроме того, я бы порекомендовал всем, кто пишет для iOS 5.0, взглянуть на Core Image и GLKView.Они в основном делают вашу работу по настройке свойств изображения (как я делаю здесь) и типа преобразования EAGLView в UIImage намного проще.

...