gpt4 book ai didi

ios - vImageBoxConvolve_ARGB8888 用法的错误 CGImageGetBytesPerRow 值

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:41:49 28 4
gpt4 key购买 nike

一开始我需要做一个快速的实时图像模糊。找到一个有用的教程 Perform a blur using vImage.

这是代码示例

-(UIImage *)boxblurImage:(UIImage *)image boxSize:(int)boxSize {
CGImageRef img = image.CGImage;

vImage_Buffer inBuffer, outBuffer;

vImage_Error error;
void *pixelBuffer;

//create vImage_Buffer with data from CGImageRef

CGDataProviderRef inProvider = CGImageGetDataProvider(img);
CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);

inBuffer.width = CGImageGetWidth(img);
inBuffer.height = CGImageGetHeight(img);
inBuffer.rowBytes = CGImageGetBytesPerRow(img);

inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);

//create vImage_Buffer for output

pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));

if(pixelBuffer == NULL)
NSLog(@"No pixelbuffer");

outBuffer.data = pixelBuffer;
outBuffer.width = CGImageGetWidth(img);
outBuffer.height = CGImageGetHeight(img);
outBuffer.rowBytes = CGImageGetBytesPerRow(img);

//perform convolution
error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);

if (error) {
NSLog(@"error from convolution %ld", error);
}

//create CGImageRef from vImage_Buffer output
//1 - CGBitmapContextCreateImage -

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

CGContextRef ctx = CGBitmapContextCreate(outBuffer.data,
outBuffer.width,
outBuffer.height,
8,
outBuffer.rowBytes,
colorSpace,
kCGImageAlphaNoneSkipLast);
CGImageRef imageRef = CGBitmapContextCreateImage (ctx);

UIImage *returnImage = [UIImage imageWithCGImage:imageRef];

//clean up
CGContextRelease(ctx);
CGColorSpaceRelease(colorSpace);

free(pixelBuffer);
CFRelease(inBitmapData);

CGImageRelease(imageRef);

return returnImage;
}

问题是函数在某些图像上抛出异常。我只找到一张图片 "Broken image" (它是 JPEG,不是 PNG)。

有异常(exception)

<Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component color space; kCGImageAlphaNoneSkipLast; 538 bytes/row.
<Error>: CGBitmapContextCreateImage: invalid context 0x0

我开始用谷歌搜索它。找到了几个解决方案。经过一段时间的调试后,我发现 CGImageGetBytesPerRow 为“损坏的图像”返回了错误的值。它适合原始图像宽度,而不是应该超过它四倍。

我尝试手动更改 CGBitmapContextCreate 中的 rowBytes,但图像上开始出现很多伪像。关键是bug很神秘,时不时出现,但还是会出现。

如何在不检查缓冲区的 rowBytes 的情况下解决它?我可以对 rowBytes 值进行一些预检查并返回原始图像,但它看起来像 hack。以及为什么某些图像(例如我们的图像)会返回错误的 rowBytes 值?

最佳答案

你看过 vImageBuffer_InitWithCGImage/vImageCreateCGImageFromBuffer 了吗?

vImage_Buffer buf = {0};
vImage_CGImageFormat fmt = {
.bitsPerComponent = 8,
.bitsPerPixel = 32,
.colorSpace = CGImageGetColorSpace(image),
.bitmapInfo = kCGImageAlphaLast | kCGBitmapByteOrderDefault
};

vImage_Error err = vImageBuffer_InitWithCGImage( &buf, &fmt, NULL, image, kvImageNoFlags ); // allocates buf.data

vImage_Buffer outBuffer;
vImageBuffer_Init( &outBuffer, buf.height, buf.width, fmt.bitsPerPixel, kvImageNoFlags);
vImageBoxConvolve_ARGB8888(&buf, &outBuffer, ...);
free(buf.data);

CGImageRef newImage = vImageCreateCGImageFromBuffer( &outBuffer, &fmt, NULL, NULL, kvImageNoAllocate, &err ); // outBuffer.data will be freed when the CGImageRef is released.

关于ios - vImageBoxConvolve_ARGB8888 用法的错误 CGImageGetBytesPerRow 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18192395/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com