admin管理员组文章数量:1435859
I am converting a UIImage
to a vImage_Buffer
.
The code looks as follows:
CGImageRef originalImageRef = [image CGImage];
CGColorSpaceRef originalColorSpace = CGImageGetColorSpace(originalImageRef);
CGColorRenderingIntent intent = CGImageGetRenderingIntent(originalImageRef);
vImage_CGImageFormat inputImageFormat =
{
.bitsPerComponent = (uint32_t) CGImageGetBitsPerComponent(originalImageRef),
.bitsPerPixel = (uint32_t) CGImageGetBitsPerComponent(originalImageRef) * (uint32_t)(CGColorSpaceGetNumberOfComponents(originalColorSpace) + (kCGImageAlphaNone != CGImageGetAlphaInfo(originalImageRef))),
.colorSpace = originalColorSpace,
.bitmapInfo = CGImageGetBitmapInfo(originalImageRef),
.version = 0,
.decode = NULL,
.renderingIntent = kCGRenderingIntentDefault
};
vImage_Error error = vImageBuffer_InitWithCGImage(inputImageBuffer, &inputImageFormat, NULL, originalImageRef, kvImageNoFlags);
if (error == kvImageNoError) {
NSLog(@"image to vimage buffer conversion complete");
} else {
NSLog(@"image to vimage buffer conversion failed");
}
But the resulting buffer colors are all different. All the Blue tones change into Yellow and so on.
I tried the following code as well:
CGImageRef sourceRef = [image CGImage];
NSUInteger sourceWidth = CGImageGetWidth(sourceRef);
NSUInteger sourceHeight = CGImageGetHeight(sourceRef);
CGDataProviderRef provider = CGImageGetDataProvider(sourceRef);
CFDataRef bitmapData = CGDataProviderCopyData(provider);
unsigned char *sourceData = (unsigned char*)calloc(sourceHeight * sourceWidth * 4, sizeof(unsigned char));
NSUInteger bytesPerPixel = 4;
NSUInteger sourceBytesPerRow = bytesPerPixel * sourceWidth;
CFDataGetBytes(bitmapData, CFRangeMake(0, CFDataGetLength(bitmapData)), sourceData);
vImage_Buffer v_image = {
.data = (void *)sourceData,
.height = sourceHeight,
.width = sourceWidth,
.rowBytes = sourceBytesPerRow
};
CFRelease(bitmapData);
But this also seems to have same problem.
Any help in this regard is highly appreciated.
I am converting a UIImage
to a vImage_Buffer
.
The code looks as follows:
CGImageRef originalImageRef = [image CGImage];
CGColorSpaceRef originalColorSpace = CGImageGetColorSpace(originalImageRef);
CGColorRenderingIntent intent = CGImageGetRenderingIntent(originalImageRef);
vImage_CGImageFormat inputImageFormat =
{
.bitsPerComponent = (uint32_t) CGImageGetBitsPerComponent(originalImageRef),
.bitsPerPixel = (uint32_t) CGImageGetBitsPerComponent(originalImageRef) * (uint32_t)(CGColorSpaceGetNumberOfComponents(originalColorSpace) + (kCGImageAlphaNone != CGImageGetAlphaInfo(originalImageRef))),
.colorSpace = originalColorSpace,
.bitmapInfo = CGImageGetBitmapInfo(originalImageRef),
.version = 0,
.decode = NULL,
.renderingIntent = kCGRenderingIntentDefault
};
vImage_Error error = vImageBuffer_InitWithCGImage(inputImageBuffer, &inputImageFormat, NULL, originalImageRef, kvImageNoFlags);
if (error == kvImageNoError) {
NSLog(@"image to vimage buffer conversion complete");
} else {
NSLog(@"image to vimage buffer conversion failed");
}
But the resulting buffer colors are all different. All the Blue tones change into Yellow and so on.
I tried the following code as well:
CGImageRef sourceRef = [image CGImage];
NSUInteger sourceWidth = CGImageGetWidth(sourceRef);
NSUInteger sourceHeight = CGImageGetHeight(sourceRef);
CGDataProviderRef provider = CGImageGetDataProvider(sourceRef);
CFDataRef bitmapData = CGDataProviderCopyData(provider);
unsigned char *sourceData = (unsigned char*)calloc(sourceHeight * sourceWidth * 4, sizeof(unsigned char));
NSUInteger bytesPerPixel = 4;
NSUInteger sourceBytesPerRow = bytesPerPixel * sourceWidth;
CFDataGetBytes(bitmapData, CFRangeMake(0, CFDataGetLength(bitmapData)), sourceData);
vImage_Buffer v_image = {
.data = (void *)sourceData,
.height = sourceHeight,
.width = sourceWidth,
.rowBytes = sourceBytesPerRow
};
CFRelease(bitmapData);
But this also seems to have same problem.
Any help in this regard is highly appreciated.
Share Improve this question edited Mar 22 at 8:23 soundflix 2,86512 gold badges16 silver badges34 bronze badges asked Mar 19 at 1:26 DidasDidas 432 bronze badges1 Answer
Reset to default 0CGImage supports a wide variety of content, including formats that are 16 bits per channel, and have non RGB colorspaces, half-float samples, etc. So the above code (second example) doesn’t necessarily handle these cases correctly. The vImage function will do conversions and such, but data provider doesn’t and it isn’t guaranteed that the source colorspace combined with a 32-bit four channel pixel make any sense. Also your assumptions about bytes per row may be invalid, but that isn’t the error you are reporting. Get the bytes per row from the data provider.
More likely, it may just be you are visualizing the contents of the vImage buffer incorrectly. I would be especially cautious of endian problems. The image could be BGRA and you might be visualizing it as ARGB or RGBA, for example. As you can see for some of these cases the alpha and blue channels can be swapped and in those cases the mostly opaque alpha will become a mostly blue image, with some swapping also of red and green. Your description sounds most like BGRA <-> RGBA, which swaps blue and red and would cause cyan to become yellow. bGRA is alpha first, little endian 32. RGBA is big endian alpha last. BGRA is the default format for iOS.
Although I’ve never seen it myself in a CGImage, this kind of color swizzle might also occur with 444 YUV content that somehow made it into a CGImage, perhaps due to an busted upstream conversion from a CVPixelBuffer. There is no colorspace description for YUV per se. instead you get a RGB colorspace and a separate conversion matrix that has to be applied outside of ColorSync. (There isn’t any YUV in ICC color profiles, which is the issue there)
What is primarily missing in this problem description is how you are visualizing the vImage buffer. You also should go find out what the colorspace and CGBitmapInfo for the image are and report back to see how you should be visualizing it. The colorspace will self report its contents using the po command in the debugger. The CGBitmapInfo bit field may or may not resolve itself in the debugger but it is fairly simple to decode by hand. You could also take the unusual step of composing a VImageConverterRef (or whatever the vimageconvert_any2any uses) for the conversion and the using po or vImageConverter_Print(converter) to dump the conversion pipeline. This would be helpful if you think the conversion itself is in error.
本文标签: iosCGImage to vImage buffer conversion leads to wrong colorsStack Overflow
版权声明:本文标题:ios - CGImage to vImage buffer conversion leads to wrong colors - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744484873a2608391.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论