如何使用ios中的vImage旋转和粘贴带alpha通道的图像?

时间:2015-01-25 00:56:24

标签: c++ ios affinetransform accelerate-framework vimage

我有一个大图像A和另一个图像B,它有一个我想要粘贴到A的alpha通道。我想在将它粘贴到A之前对B应用仿射变换。有什么步骤要做这在c ++中使用iOS中的vImage?

2 个答案:

答案 0 :(得分:1)

我怀疑你能够在这里发布任何答案吗?它们中没有足够的细节来帮助那些有这样问题的人开始。

这是你的工作答案:

- (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 );

}

答案 1 :(得分:0)

假设每个组件8位,4个通道数据:

  1. Unpremultiply A - vImageUnpremultiplyData_ARGB8888
  2. 从B中提取alpha通道 - vImageExtractChannel_ARGB8888
  3. 转换B - vImageAffineWarp_Planar8
  4. 从A - vImageExtractChannel_ARGB8888
  5. 中提取Alpha通道
  6. 将两个alpha通道相乘 - vImagePremultiplyData_Planar8
  7. 将结果写入A - vImageOverwriteChannels_ARGB8888
  8. 预乘A - vImagePremultiplyData_ARGB8888
  9. 如果你真的想用A替换A的alpha而不是将它们合成,请跳过步骤4和5.

    如果你在一条扫描线上完成所有7个步骤,那么整个过程将会运行得更快,然后再转到下一个扫描线。 kvImageDoNotTile和dispatch_apply()可以用来简单地多线程。

      

    预乘:您可以选择是否使用图像   是预乘还是不是。合成的性能优势   预乘图像通常被夸大了。它只是略微多一点   努力将非预乘图像合成为预乘的图像   表面比复合预乘的表面。预乘导致大多数图像滤波器出现问题   在一堆前所未有的工作中再次进行预乘和预乘。它也是   导致一些精确损失。如上所示,如果图像是   不进行预乘,那么你想要做的操作就变得多了   简单。它可以是一个简单的步骤2和6,或一次通过   with vImageSelectChannels_ARGB8888 / vImagePermuteChannelsWithMaskedInsert_ARGB8888()。