[英]How can I rotate and paste image with alpha channel using vImage in ios?
我有一个大图像A和另一个图像B,该图像具有要粘贴到A中的Alpha通道。我想在将B贴上A之前对其进行仿射变换。在c ++中执行此步骤的步骤是什么在iOS中使用vImage?
I doubt you were able to get any of the answers posted here to work; 我怀疑您是否可以在此处发布任何答案才能正常工作; there are just not enough specifics in them to help someone who had a question like this to begin with.
只是其中没有足够的细节来帮助遇到此类问题的人。
Here's your working answer: 这是您的工作答案:
- (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 );
} }
Assuming 8-bits per component, 4 channel data: 假设每个组件8位,则4通道数据:
If you really wanted to replace the alpha of A with B rather than composite them together, skip steps 4 and 5. 如果您确实想用B代替A的alpha而不是将它们组合在一起,请跳过第4步和第5步。
The whole thing will run quite a bit faster if you do all 7 steps on one scanline, before moving on to the next scanline. 如果在转到下一条扫描线之前在一条扫描线上执行所有7个步骤,则整个过程将运行得更快。 kvImageDoNotTile and dispatch_apply() can be used to multithread it fairly simply.
kvImageDoNotTile和dispatch_apply()可用于相当简单地对其进行多线程处理。
On premultiplication: You may have a choice as to whether the images are premultiplied or not.
关于预倍增:您可以选择是否对图像进行预倍增。 The performance benefits for compositing of premultiplied images is usually overstated.
通常会夸大预合成图像的性能优势。 It is only marginally more work to composite a non-premultiplied image into a premultiplied surface than it is to composite a premultiplied one.
将未预乘的图像合成到预乘的曲面中,仅比将预乘的图像合成要多得多。 Premultiplication causes problems for most image filters, resulting in a bunch of work unpremultiplying and premultiplying again.
预乘会导致大多数图像滤镜出现问题,从而导致一堆工作无法进行预乘并再次进行预乘。 It also causes some precision loss.
这也会导致一些精度损失。 As you can see above, if the images are not premultiplied, then the operations you want to do become much simpler.
正如您在上面看到的,如果图像没有预乘,那么您要执行的操作将变得更加简单。 It could be a simple as just steps 2 and 6, or a single pass with vImageSelectChannels_ARGB8888 / vImagePermuteChannelsWithMaskedInsert_ARGB8888().
只需第2步和第6步就可以很简单,也可以单次使用vImageSelectChannels_ARGB8888 / vImagePermuteChannelsWithMaskedInsert_ARGB8888()。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.