首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在ios中使用vImage使用alpha通道旋转和粘贴图像?

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

Stack Overflow用户
提问于 2015-01-25 00:56:23
回答 2查看 264关注 0票数 0

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-13 16:08:18

我怀疑你是否能够在这里得到任何答案来发挥作用,只是其中没有足够的细节来帮助那些一开始就有类似问题的人。

这是你的工作答案:

代码语言:javascript
复制
- (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
EN

Stack Overflow用户

发布于 2015-01-27 04:53:49

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

  1. 非乘A- vImageUnpremultiplyData_ARGB8888
  2. 从B -- vImageExtractChannel_ARGB8888中提取α通道
  3. 变换B- vImageAffineWarp_Planar8
  4. 从A- vImageExtractChannel_ARGB8888中提取α通道
  5. 将两个alpha通道相乘-- vImagePremultiplyData_Planar8
  6. 将结果写入A- vImageOverwriteChannels_ARGB8888
  7. 预乘A- vImagePremultiplyData_ARGB8888

如果您真的想用B替换A的alpha,而不是将它们组合在一起,请跳过步骤4和步骤5。

如果您在一条扫描线上执行所有7步操作,然后再转到下一条scanline,整个过程将运行得更快一些。kvImageDoNotTile和dispatch_apply()可以简单地用于多线程。

关于预乘法:您可以选择图像是否被预乘。合成预乘图像的性能优势通常被夸大了。将非乘乘图像合成到预乘表面的工作量比将预乘图像合成的工作量要小得多。预乘会给大多数图像滤波器带来问题,导致大量的非乘法和预乘工作。这也造成了一些精度损失。正如您在上面所看到的,如果图像没有预乘,那么您想要做的操作就会变得简单得多。它可以是简单的步骤2和步骤6,也可以是vImageSelectChannels_ARGB8888 /vImageSelectChannels_ARGB8888的一次传递。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28132046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档