使用解码数组创建 CGImage 时,输出的所有像素都有少量偏移

When creating a CGImage with a decode array, the output has all of it's pixels offset by a small amount

非常奇怪的行为,但我认为我已经尽可能缩小了问题范围

我有一个NSImage,暂且称它为inputImage。它由 CGColorSpaceCreateDeviceGray 中的 NSBitmapImageRep 表示,如果重要的话

我想用它创建一个 CGImageRef,但颜色相反。

  NSData *data = [inputImage TIFFRepresentation];
  CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

  NSBitmapImageRep *maskedRep = (NSBitmapImageRep*)[inputImage representations][0];
  CGFloat decode[] = {0.0, 1.0};

  maskRef = CGImageMaskCreate(maskedRep.pixelsWide,
                              maskedRep.pixelsHigh,
                              8,
                              maskedRep.bitsPerPixel,
                              maskedRep.bytesPerRow,
                              provider,
                              decode,
                              false);

  NSImage *testImage = [[NSImage alloc] initWithCGImage:maskRef size:NSMakeSize(1280,1185)]; //the size of the image, hard-coded for testing
  NSLog(@"testimage: %@", testImage);

问题是当我查看 testImage 时,所有像素都略微偏离原始图像的右侧。

inputImage:

testImage:

如果将图片保存下来会更容易查看,但您会注意到 testImage 中的所有内容都向右偏移了大约 5 个像素左右。您会在 testImage

中的黑色内容左侧看到一个白色间隙

在我的 5 行代码中的某处,我以某种方式移动了我的图像。有人知道这是怎么发生的吗?我目前怀疑 TIFFRepresentation

您传递给 CGImageMaskCreate() 的数据提供者应该是其他参数指定形式的原始像素,而不是图像文件格式。您不应该传递 TIFF 数据。坦率地说,我很惊讶你得到的东西与你的原始图像非常相似,而不是 noise/garbage。我猜 TIFF 数据没有被压缩,纯属偶然。实际上,您可以在遮罩的 upper-left 处看到一些噪音,即被解释为像素的 TIFF header。

可能,您最好的选择是从 inputImage 创建一个 CGImage(或者,根据 inputImage 的创建方式,跳过 NSImage 并创建 CGImage 直接从文件中使用 CGImageSource API 或 CGImageCreateWith{JPEG,PNG}DataProvider())。要从 NSImage 获取 CGImage,请使用 -CGImageForProposedRect:context:hints:.

然后,从 CGImage 获取数据提供者并使用从第一个 CGImage 使用各种 CGImageGet... 函数。