我尝试使用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;
答案 0 :(得分:1)
使用vImage
表示仅使用像素。所以你绝对不能使用图像(或imageRep)的大小,你只使用pixelsWide和pixelsHigh。将所有size.width
替换为pixelsWide
,将所有size.height
替换为pixelsHigh
。 Apple有vImage的示例代码,他们使用大小值!不要相信他们!并非所有Apple示例代码都是正确的。
图像或imageRep的大小决定了在屏幕(或打印机)上绘制图像的大小。尺寸值具有长度的尺寸,单位是米,厘米,英寸或(如在可可中)1/72英寸即点。它们表示为浮点值。
PixelsWide和pixelsHigh没有维度,没有单位(它们只是数字),并表示为int值。
您的代码中可能存在更多错误,但第一步应该是替换所有大小值。
答案 1 :(得分:1)
严格来说,您需要kCGBitmapByteOrderDefault而不是kCGBitmapByteOrder32Big。对于24位像素格式,32Big没有多大意义。
这似乎是一个薄弱环节:
destinationBuffer.rowBytes = [destinationImageData length]/size.height;
检查是否是正确的号码。
输出图片有助于诊断问题。还要检查控制台,看看CG是否给你任何喷射。您是否尝试过使用kvImagePrintDiagnosticsToConsole的vImageCreateCGImageFromBuffer()来查看它是否有话要说?
答案 2 :(得分:0)
使用vImage意味着仅使用像素。所以你绝对不能使用图像(或imageRep)的大小,你只使用pixelsWide和pixelsHigh。将所有size.width替换为pixelsWide,将所有size.height替换为pixelsHigh。 Apple有vImage的示例代码,他们使用大小值!不要相信他们!并非所有Apple示例代码都是正确的。
图像或imageRep的大小决定了在屏幕(或打印机)上绘制图像的大小。尺寸值具有长度的尺寸,单位是米,厘米,英寸或(如在可可中)1/72英寸即点。它们表示为浮点值。
PixelsWide和pixelsHigh没有维度,没有单位(它们只是数字),并表示为int值。
您的代码中可能存在更多错误,但第一步应该是替换所有大小值。