0

这段代码产生了一些非常奇怪的输出。为什么?我所做的只是复制图像。

NSData *data = [NSData dataWithContentsOfFile: @"/Users/Jojo/Desktop/k2.jpg"];
NSBitmapImageRep *image = [NSBitmapImageRep imageRepWithData: data];

assert(image.samplesPerPixel == 3);
assert(image.isPlanar == NO);

uint8_t *buffer = [image bitmapData];

NSBitmapImageRep *rtn = [[NSBitmapImageRep alloc]
                        initWithBitmapDataPlanes:&buffer
                        pixelsWide:image.pixelsWide
                        pixelsHigh:image.pixelsHigh
                        bitsPerSample:8
                        samplesPerPixel:3
                        hasAlpha:NO
                        isPlanar:NO
                        colorSpaceName:NSDeviceRGBColorSpace
                        bytesPerRow: image.pixelsWide*3
                        bitsPerPixel: 8*3];

NSData *newJpg = [rtn representationUsingType:NSJPEGFileType properties:nil];
[newJpg writeToFile:@"/Users/Jojo/Desktop/and.jpg" atomically:YES];

例子:

普通的 破碎的

4

1 回答 1

1

我不知道你想达到什么目标;只是现有图像的副本?是[image copy]不是不够好?除此之外,您的代码至少有两个大错误:您必须明确区分图像的属性和这些属性的存储方式。您忘记了可能存在或不存在的填充字节。这经常从一个 OSX 版本更改为下一个 OSX 版本。因此,在您的源图像中,每个像素的样本数为 3,但它们存储在 4 个字节中(原因:存储访问优化)。因此bitsPerPixel: 8*3是错误的,所以也是bytesPerRow。所以你的源图像有1600 bytes per row 并且每个像素都存储在32 bits(== 1 个填充字节)。您必须为新的 NSBitmapImageRep 提供与源 imageRep 完全相同的(缓冲区)参数。这意味着:最后两个参数(创建一个新的代表)应该是:

bytesPerRow: [image bytesPerRow]
bitsPerPixel: [image bitsPerPixel]

bitmapFormat使用参数表示像素的组件是 RGB 还是 BGR 以及 alpha 值在哪里(或填充字节)也很有用。

也许最好使用copy- 方法?

于 2014-03-08T15:34:45.587 回答