CGImageCreate с CGColorSpaceCreateDeviceGray на iOS12 - PullRequest
0 голосов
/ 23 октября 2018

Я использовал CGImageCreate с CGColorSpaceCreateDeviceGray для преобразования буфера (CVPixelBufferRef) в изображение в градациях серого.Это было очень быстро и работало хорошо до iOS 12 ... теперь возвращаемое изображение пусто.

Код выглядит следующим образом:

bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst;

CGDataProviderRef provider = CGDataProviderCreateWithData((void *)i_PixelBuffer,
                                                              sourceBaseAddr,
                                                              sourceRowBytes * height,
                                                              ReleaseCVPixelBuffer);
    retImage = CGImageCreate(width,
                             height,
                             8,
                             32,
                             sourceRowBytes,
                             CGColorSpaceCreateDeviceGray(),
                             bitmapInfo,
                             provider,
                             NULL,
                             true,
                             kCGRenderingIntentDefault);
    CGDataProviderRelease(provider);

Это известная ошибка в iOS 12?Если серый цвет устройства больше не поддерживается в этой функции, можете ли вы предложить мне другой способ сделать это?

Обратите внимание, что преобразование должно занять менее 0,1 секунды для изображения 4K.

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Я наконец нашел обходной путь для своей цели.Обратите внимание, что CVPixelBuffer исходит от видеокамеры.

  • Изменен формат выходного пикселя камеры на
    kCVPixelFormatType_420YpCbCr8BiPlanarFullRange (AVCaptureVideoDataOutput)

Код:

// some code

colorSpace = CGColorSpaceCreateDeviceGray();
sourceRowBytes = CVPixelBufferGetBytesPerRowOfPlane(i_PixelBuffer, 0);
sourceBaseAddr = (unsigned char*)CVPixelBufferGetBaseAddressOfPlane(i_PixelBuffer,0);
bitmapInfo = kCGImageByteOrderDefault;

// some code

CGContextRef context = CGBitmapContextCreate(sourceBaseAddr,
                                             width,
                                             height,
                                             8,
                                             sourceRowBytes,
                                             colorSpace,
                                             bitmapInfo);
retImage = CGBitmapContextCreateImage(context);

// some code

Вы также можете посмотреть на этот пост: 420YpCbCr8BiPlanarVideoRange To YUV420? / Как скопировать Y иCbcr самолет в одноместный самолет?

0 голосов
/ 23 октября 2018

Согласно списку Поддерживаемых форматов пикселей в Руководстве по программированию Quartz 2D , iOS не поддерживает 32 бита на пиксель с серыми цветовыми пространствами.И даже в macOS 32 bpp grey требует использования kCGBitmapFloatComponents (и данных с плавающей точкой).

Ваши данные действительно 32 bpp?Если это так, это плавать?Что вы используете для bitmapInfo?

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

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

...