使用偏移量缩放 vImage_Buffer - Cocoa Objective C
Posted
技术标签:
【中文标题】使用偏移量缩放 vImage_Buffer - Cocoa Objective C【英文标题】:Scale vImage_Buffer with offset - Cocoa Objective C 【发布时间】:2020-08-07 13:40:04 【问题描述】:我正在尝试使用 vImage_Buffer 缩放图像,下面的代码对我有用。我的麻烦是我想保持源图像的纵横比,所以我可能需要添加xOffset
或yOffset
。下面的代码仅适用于yOffset
。我如何也可以使用xOffset
缩放图像。我无法使用CGContext
进行缩放,因为这会影响性能。
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
size_t finalWidth = 1080;
size_t finalHeight = 720;
size_t sourceWidth = CVPixelBufferGetWidth(imageBuffer);
size_t sourceHeight = CVPixelBufferGetHeight(imageBuffer);
CGRect aspectRect = AVMakeRectWithAspectRatioInsideRect(CGSizeMake(sourceWidth, sourceHeight), CGRectMake(0, 0, finalWidth, finalHeight));
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
size_t startY = aspectRect.origin.y;
size_t yOffSet = (finalWidth*startY*4);
CVPixelBufferLockBaseAddress(imageBuffer, 0);
void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
void* destData = malloc(finalHeight * finalWidth * 4);
vImage_Buffer srcBuffer = (void *)baseAddress, sourceHeight, sourceWidth, bytesPerRow;
vImage_Buffer destBuffer = (void *)destData+yOffSet, aspectRect.size.height, aspectRect.size.width, aspectRect.size.width * 4;
vImage_Error err = vImageScale_ARGB8888(&srcBuffer, &destBuffer, NULL, 0);
【问题讨论】:
【参考方案1】:没有双关语,但您确实应该阅读 Accelerate.framework 文档。
将malloc
替换为calloc
...
void *destData = calloc(finalHeight * finalWidth * 4);
...将所有字节归零(或使用任何其他方式)。
vImage_Buffer.rowBytes
文档是怎么说的?
图像中一个像素行的开头和下一个像素行之间的距离(以字节为单位),包括它们之间的任何未使用空间。
rowBytes 值必须至少是宽度乘以像素大小,其中像素大小取决于图像格式。您可以提供更大的值,在这种情况下,额外的字节将超出每行像素的末尾。您可能希望这样做是为了提高性能,或者在不复制数据的情况下在更大的图像中描述图像。额外的字节不被视为由 vImage 缓冲区表示的图像的一部分。 为图像分配浮点数据时,通过将字节分配为 4 的整数倍来保持数据 4 字节对齐。为获得最佳性能,请将字节分配为 16 的整数倍。
看下图:
红色圆圈(左上角)是offset
,从缓冲区开始,我们计算一下(假设每个像素4字节):
size_t startY = aspectRect.origin.y;
size_t startX = aspectRect.origin.x;
size_t offset = 4 * (finalWidth * startY + startX);
图像中一个像素行的开头和下一个像素行之间的距离(包括它们之间的任何未使用空间)之间的距离(以字节为单位)为 让我们修复finalWidth * 4
(另外两个圆圈之间的红线)。
destBuffer
:vImage_Buffer destBuffer =
(void *)destData+offset,
aspectRect.size.height,
aspectRect.size.width,
finalWidth * 4
;
【讨论】:
非常感谢。它就像一个魅力。当我从目标缓冲区创建 CVImagebufferRef 时,x0ffset
的图像的颜色空间不同。它非常适合yOffset
的图像。你有什么想法吗?
我找到了原因。这是因为原始值是浮点数,我们需要将其转换为size_t
,因为我们正在处理内存。用相同的方式更新了答案。以上是关于使用偏移量缩放 vImage_Buffer - Cocoa Objective C的主要内容,如果未能解决你的问题,请参考以下文章