Извините, для этого вопроса, я знаю, есть аналогичный вопрос, но я не могу получить ответ на работу. Вероятно, какая-то глупая ошибка на моей стороне ;-)iOS: Наложение двух изображений с помощью альфа-экрана
Я хочу наложить два изображения с помощью Alpha на iOS. Изображения, взятые из двух видеороликов, считанные AssetReader и хранящиеся в двух CVPixelBuffer. Я знаю, что канал Alpha не сохраняется в видео, поэтому я получаю его из третьего файла. Все данные выглядят отлично. Проблема заключается в наложении, если я делаю это на экране с помощью [CIContext drawImage], все в порядке! Но если я делаю это за кадром, потому что формат видео не идентичен формату экрана, я не могу заставить его работать: 1. drawImage действительно работает, но только на экране 2. render: toCVPixelBuffer работает, но игнорирует Альфа 3. CGContextDrawImage, кажется, не делать ничего вообще (даже не сообщение об ошибке)
Так может кто-нибудь дать мне представление о том, что это не так:
Init: ... (много кода перед) Настройка цветового пространства и растрового контекста
if(outputContext)
{
CGContextRelease(outputContext);
CGColorSpaceRelease(outputColorSpace);
}
outputColorSpace = CGColorSpaceCreateDeviceRGB();
outputContext = CGBitmapContextCreate(CVPixelBufferGetBaseAddress(pixelBuffer), videoFormatSize.width, videoFormatSize.height, 8, CVPixelBufferGetBytesPerRow(pixelBuffer), outputColorSpace,(CGBitmapInfo) kCGBitmapByteOrderDefault |kCGImageAlphaPremultipliedFirst);
... (много кода после)
Чертеж:
CIImage *backImageFromSample;
CGImageRef frontImageFromSample;
CVImageBufferRef nextImageBuffer = myPixelBufferArray[0];
CMSampleBufferRef sampleBuffer = NULL;
CMSampleTimingInfo timingInfo;
//draw the frame
CGRect toRect;
toRect.origin.x = 0;
toRect.origin.y = 0;
toRect.size = videoFormatSize;
//background image always full size, this part seems to work
if(drawBack)
{
CVPixelBufferLockBaseAddress(backImageBuffer, kCVPixelBufferLock_ReadOnly);
backImageFromSample = [CIImage imageWithCVPixelBuffer:backImageBuffer];
[coreImageContext render:backImageFromSample toCVPixelBuffer:nextImageBuffer bounds:toRect colorSpace:rgbSpace];
CVPixelBufferUnlockBaseAddress(backImageBuffer, kCVPixelBufferLock_ReadOnly);
}
else
[self clearBuffer:nextImageBuffer];
//Front image doesn't seem to do anything
if(drawFront)
{
unsigned long int numBytes = CVPixelBufferGetBytesPerRow(frontImageBuffer)*CVPixelBufferGetHeight(frontImageBuffer);
CVPixelBufferLockBaseAddress(frontImageBuffer, kCVPixelBufferLock_ReadOnly);
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, CVPixelBufferGetBaseAddress(frontImageBuffer), numBytes, NULL);
frontImageFromSample = CGImageCreate (CVPixelBufferGetWidth(frontImageBuffer) , CVPixelBufferGetHeight(frontImageBuffer), 8, 32, CVPixelBufferGetBytesPerRow(frontImageBuffer), outputColorSpace, (CGBitmapInfo) kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst, provider, NULL, NO, kCGRenderingIntentDefault);
CGContextDrawImage (outputContext, inrect, frontImageFromSample);
CVPixelBufferUnlockBaseAddress(frontImageBuffer, kCVPixelBufferLock_ReadOnly);
CGImageRelease(frontImageFromSample);
}
Любые идеи кто-нибудь?
Если вы ищете, возможно, лучший способ сохранить альфа-видео в вашем приложении расслоении, то есть взглянуть на: http://stackoverflow.com/a/21079559/763355 – MoDJ
Да, я видел примеры, которые разделяют видео с Alpha на два видео один цвет + один оттенок серого, но я решил против него. Идея моей реализации заключалась в том, чтобы использовать GPU для кодирования видео и CPU для кодирования маски. Это позволяет мне делать это в реальном времени даже с камеры ... – BetaVersion