Искажение цвета в CGImageCreate - PullRequest
7 голосов
/ 29 марта 2012

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

enter image description here

Кола красная, все хорошо.

Когда я запускаю свой код снимка, я получаю это:

enter image description here

Кола синего цвета ... откуда это взялось?

Я пытался связываться с некоторыми параметрами, но в итоге не получил изображения вообще,Вот мой код снимка:

int bitsPerComponent = 8;
    int bitsPerPixel = 32;
    int bytesPerRow = [cameraVideo bufRowBytes];
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, [cameraVideo bufDataPtr], [cameraVideo bufWidth]*[cameraVideo bufHeight]*4, NULL);

    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGImageAlphaNoneSkipLast;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentPerceptual;

    CGImageRef imageRef = CGImageCreate( [cameraVideo bufWidth], [cameraVideo bufHeight], bitsPerComponent, bitsPerPixel,
                                        bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

    CGColorSpaceRelease(colorSpaceRef);

Я нахожусь в своем уме, поэтому, если кто-то может понять, что я делаю неправильно, пожалуйста, дайте мне знать.*

Вот окончательный код:

if (cameraVideo.ARPixelFormat == kCVPixelFormatType_32ARGB) {
    bitmapInfo = kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipFirst;
} else {
    bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst;
}

1 Ответ

12 голосов
/ 31 марта 2012

Похоже, ваши каналы R (красный) и B (синий) поменялись местами. Камера заполняет буфер в порядке BGR, но вы говорите CGImage, что данные в порядке RGB. Я полагаю, что вы управляете этим, используя одну из kCGBitmapByteOrder... констант в вашем CGBitmapInfo. Попробуйте установить bitmapInfo так:

CGBitmapInfo bitmapInfo = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big;

Если это не сработает, попробуйте другие kCGBitmapByteOrder... константы (kCGBitmapByteOrder32Little, kCGBitmapByteOrder16Big, kCGBitmapByteOrder16Little).

EDIT

В примере проекта Apple SquareCam есть файл с именем SquareCam/SqareCamViewController.m (да, в имени файла написано слово «Квадрат»). Содержит этот код:

    sourcePixelFormat = CVPixelBufferGetPixelFormatType( pixelBuffer );
    if ( kCVPixelFormatType_32ARGB == sourcePixelFormat )
        bitmapInfo = kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipFirst;
    else if ( kCVPixelFormatType_32BGRA == sourcePixelFormat )
        bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst;
    else
        return -95014; // only uncompressed pixel formats

Возможно, вы захотите сделать то же самое.

...