【问题标题】:vImage not putting channels correctly back togethervImage 没有将通道正确地重新组合在一起
【发布时间】:2013-07-25 09:02:44
【问题描述】:

我尝试使用 vImageConvert_RGB888toPlanar8 从图像中提取所有 3 个通道,然后使用 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;

【问题讨论】:

    标签: objective-c macos cocoa image-processing vimage


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 我已经用 pixelHigh 测试过它,但它仍然没有工作。然后我在代码中手动输入了图像的确切像素值,但它仍然不起作用。
    【解决方案2】:

    严格来说,您需要 kCGBitmapByteOrderDefault 而不是 kCGBitmapByteOrder32Big。 32Big 对于 24 位像素格式没有多大意义。

    这似乎是一个薄弱环节:

    destinationBuffer.rowBytes = [destinationImageData length]/size.height;
    

    检查它是否是正确的数字。

    输出图片有助于诊断问题。还要检查控制台,看看 CG 是否给你任何喷射。你试过 vImageCreateCGImageFromBuffer() 和 kvImagePrintDiagnosticsToConsole 看看它有什么要说的吗?

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-24
        • 2020-12-11
        • 2020-05-09
        • 2018-02-10
        • 2021-02-16
        • 1970-01-01
        • 2012-12-14
        相关资源
        最近更新 更多