빠른 실시간 이미지 흐림을 수행해야합니다. 코드 샘플vImageBoxConvolve_ARGB8888 사용에 대한 CGImageGetBytesPerRow 값이 잘못되었습니다.
-(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;
}
문제는 그 기능은 일부 이미지에 예외가 발생 여기서 유용한 가이드 Perform a blur using vImage.
발견된다. 하나의 이미지 "Broken image" (JPEG, PNG가 아님) 만 있습니다.
내가 그것을 구글 시작을 제외하고
<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
이 "깨진 이미지"에 대해 잘못된 값을 반환한다는 것을 발견했습니다. 원래의 이미지 너비에 맞게 4 배를 초과하지 않아도됩니다.
rowBytes
을 수동으로 CGBitmapContextCreate
으로 변경하려고 시도했지만 이미지에 많은 아티팩트가 표시되기 시작했습니다. 요점은 버그는 신비스럽고 때로는 나타나지만 여전히 그렇다는 것입니다.
버퍼의 rowBytes
을 확인하지 않고 어떻게 해결할 수 있습니까? rowBytes
값의 사전 검사를 수행하고 원본 이미지를 반환 할 수 있지만 해킹처럼 보입니다. 그리고 우리의 이미지처럼 일부 이미지가 잘못 rowBytes
값을 반환하도록 어떻게 됐습니까?