У меня есть большое изображение A и другое изображение B, в котором есть альфа-канал, который я хотел бы вставить в A. Я хочу применить аффинное преобразование к B, прежде чем прикрепить его к A. Каковы шаги для этого в c ++ используя vImage в iOS?
Я сомневаюсь, что вы смогли получить любой из ответов, опубликованных здесь, для работы; в них просто не хватает специфики, чтобы помочь кому-то, у кого был такой вопрос, для начала.
Вот ваш рабочий ответ:
- (CVPixelBufferRef)copyRenderedPixelBuffer:(CVPixelBufferRef)pixelBuffer {
CVPixelBufferLockBaseAddress( pixelBuffer, 0 );
unsigned char *base = (unsigned char *)CVPixelBufferGetBaseAddress( pixelBuffer );
size_t width = CVPixelBufferGetWidth( pixelBuffer );
size_t height = CVPixelBufferGetHeight( pixelBuffer );
size_t stride = CVPixelBufferGetBytesPerRow( pixelBuffer );
//size_t extendedWidth = stride / sizeof( uint32_t ); // each pixel is 4 bytes/32 bits
vImage_Buffer _img = {
.data = base,
.height = height,
.width = width,
.rowBytes = stride
};
size_t pixelBufferSize = (stride * height) / sizeof(uint8_t);
void* gBuffer = malloc(pixelBufferSize);
vImage_Buffer _dstG = {
.data = gBuffer,
.height = height / sizeof(uint8_t),
.width = width / sizeof(uint8_t),
.rowBytes = stride / sizeof(uint8_t)
};
vImage_Error err;
const uint8_t map[4] = { 3, 2, 1, 0 };
err = vImagePermuteChannels_ARGB8888(&_img, &_img, map, kvImageNoFlags);
if (err != kvImageNoError)
NSLog(@"Error: %ld", err);
err = vImageExtractChannel_ARGB8888(&_img, &_dstG, 2, kvImageNoError);
if (err != kvImageNoError)
NSLog(@"Error: %ld", err);
err = vImageEqualization_Planar8(&_dstG, &_dstG, kvImageNoError);
if (err != kvImageNoError)
NSLog(@"Error: %ld", err);
err = vImageContrastStretch_Planar8( &_dstG, &_dstG, kvImageNoError );
if (err != kvImageNoError)
NSLog(@"Error: %ld", err);
err = vImageOverwriteChannels_ARGB8888(&_dstG, &_img, &_img, 0x2, kvImageNoError);
if (err != kvImageNoError)
NSLog(@"Error: %ld", err);
err = vImagePermuteChannels_ARGB8888(&_img, &_img, map, kvImageNoFlags);
if (err != kvImageNoError)
NSLog(@"Error: %ld", err);
CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );
free(gBuffer);
return (CVPixelBufferRef)CFRetain( pixelBuffer );
}
Предполагая 8 бит на компонент, 4 канала данных:
Если вы действительно хотите заменить альфа A на B, а не объединять их вместе, пропустите шаги 4 и 5.
Все это будет работать немного быстрее, если вы выполните все 7 шагов на одной линии сканирования, прежде чем перейти к следующей линии сканирования. kvImageDoNotTile и dispatch_apply () могут использоваться для многопоточности довольно просто.
По предварительному умножению: у вас может быть выбор относительно того, являются ли изображения
предварительно умножаются или нет. Преимущества производительности для композитинга
Предварительно умноженные изображения обычно завышены. Это лишь незначительно больше
работа по объединению без предварительного умножения изображения в предварительно умноженное
поверхности, чем составить предварительно умноженную. Преумножение вызывает проблемы для большинства фильтров изображений, в результате чего
в кучу работ опять неумножают и снова умножают. Это также
вызывает некоторую потерю точности. Как вы можете видеть выше, если изображения
без предварительного умножения, то операции, которые вы хотите сделать, становятся намного
проще. Это может быть просто как шаги 2 и 6, или один проход
с vImageSelectChannels_ARGB8888 / vImagePermuteChannelsWithMaskedInsert_ARGB8888 ().