NSBitmapImageRep错误

时间:2014-03-08 14:03:24

标签: objective-c macos appkit nsbitmapimagerep

此代码产生一些非常奇怪的输出。为什么? 我所做的只是复制一张图片。

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];

示例:

normal broken

1 个答案:

答案 0 :(得分:0)

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

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

使用参数bitmapFormat也很有用,它可以说明像素的成分是RGB还是BGR,以及alpha值是(或填充字节)。

也许最好使用copy - 方法?