objective-c - vImage 未将 channel 正确地重新组合在一起

标签 objective-c macos cocoa image-processing vimage

我尝试使用 vImageConvert_RGB888toPlanar8 从图像中提取所有 3 个 channel ,然后使用 vImageConvert_Planar8toRGB888 将它们放回一起,但图像完全困惑了。这是为什么?

vImage_Buffer blueBuffer;
blueBuffer.data = (void*)blueImageData.bytes;
blueBuffer.width = size.width;
blueBuffer.height = size.height;
blueBuffer.rowBytes = [blueImageData length]/size.height;

vImage_Buffer rBuffer;
rBuffer.width = size.width;
rBuffer.height = size.height;
rBuffer.rowBytes = size.width;
void *rPixelBuffer = malloc(size.width * size.height);
if(rPixelBuffer == NULL)
{
    NSLog(@"No pixelbuffer");
}
rBuffer.data = rPixelBuffer;

vImage_Buffer gBuffer;
gBuffer.width = size.width;
gBuffer.height = size.height;
gBuffer.rowBytes = size.width;
void *gPixelBuffer = malloc(size.width * size.height);
if(gPixelBuffer == NULL)
{
    NSLog(@"No pixelbuffer");
}
gBuffer.data = gPixelBuffer;

vImage_Buffer bBuffer;
bBuffer.width = size.width;
bBuffer.height = size.height;
bBuffer.rowBytes = size.width;
void *bPixelBuffer = malloc(size.width * size.height);
if(bPixelBuffer == NULL)
{
    NSLog(@"No pixelbuffer");
}
bBuffer.data = bPixelBuffer;

vImageConvert_RGB888toPlanar8(&blueBuffer, &rBuffer, &gBuffer, &bBuffer, kvImageNoFlags);

size_t destinationImageBytesLength = size.width*size.height*3;
const void* destinationImageBytes = valloc(destinationImageBytesLength);
NSData* destinationImageData = [[NSData alloc] initWithBytes:destinationImageBytes length:destinationImageBytesLength];
vImage_Buffer destinationBuffer;
destinationBuffer.data = (void*)destinationImageData.bytes;
destinationBuffer.width = size.width;
destinationBuffer.height = size.height;
destinationBuffer.rowBytes = [destinationImageData length]/size.height;

vImage_Error result = vImageConvert_Planar8toRGB888(&rBuffer, &gBuffer, &bBuffer, &destinationBuffer, 0);
NSImage* image = nil;
if(result == kvImageNoError)
{
    //TODO: If you need color matching, use an appropriate colorspace here
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)(destinationImageData));
    CGImageRef finalImageRef = CGImageCreate(size.width, size.height, 8, 24, destinationBuffer.rowBytes, colorSpace, kCGBitmapByteOrder32Big|kCGImageAlphaNone, dataProvider, NULL, NO, kCGRenderingIntentDefault);
    CGColorSpaceRelease(colorSpace);
    CGDataProviderRelease(dataProvider);
    image = [[NSImage alloc] initWithCGImage:finalImageRef size:NSMakeSize(size.width, size.height)];
    CGImageRelease(finalImageRef);
}
free((void*)destinationImageBytes);
return image;

最佳答案

使用vImage意味着仅使用像素。所以你绝对不能使用图像(或imageRep)的大小,你只能使用pixelsWide和pixelsHigh。将所有 size.width 替换为 pixelsWide,将所有 size.height 替换为 pixelsHigh。苹果有 vImage 的示例代码,他们使用大小值!不要相信他们!并非所有 Apple 示例代码都是正确的。

图像或 imageRep 的大小决定了在屏幕(或打印机)上绘制图像的大小。尺寸值具有长度尺寸,单位为米、厘米、英寸或(如 Cocoa 中)1/72 英寸,又称磅。它们表示为浮点值。

PixelsWide 和 PixelsHigh 没有维度和单位(它们只是数字),并表示为 int 值。

您的代码中可能存在更多错误,但第一步应该是替换所有大小值。

关于objective-c - vImage 未将 channel 正确地重新组合在一起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17853518/

相关文章:

ios - 在 init 中操作由 Objective-C 中的子类设置的属性

macos - 苹果钥匙串(keychain)私钥/公钥问题

ruby - Homebrew 如何检查已安装的 gem?

c++ - 在没有 Xcode 的 Mac Bundle 中嵌入框架

objective-c - "Symbol not found"在 10.6 上测试 Mac OS X 10.7 特定代码时崩溃

cocoa - CoreData - 如何创建 NSManagedObject 子类的子类(世代间隙模式)

objective-c - 如果它们都具有相同的 IBAction,如何定义按下哪个按钮?

ios - UITableView 行选择故障?

c++ - 碳到 cocoa 转换库?

macos - 有没有人设置tomcat来使用mod_jk运行虚拟主机