Pregunta

This code produces some very strange output. Why? All I do is copying an image.

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

Example:

normal broken

¿Fue útil?

Solución

I do not know what you want to achieve; only a copy of an existing image? Is a [image copy] not good enough? Besides this your code has at least two big bugs: you have to make a clear difference between the properties of an image and how these properties are stored. You forgot padding bytes, which may exist or not exist. This changed often from one OSX version to the next OSX version. So in your source image the number of samples per pixel is 3, but they are stored in 4 bytes (reason: storage access optimization). And therefore bitsPerPixel: 8*3 is wrong and so is bytesPerRow. So your source image has 1600 bytes per row and each pixel is stored in 32 bits (== 1 padding byte). You have to feed the new NSBitmapImageRep with exactly the same (buffer-)parameters as of the source imageRep. This means: the last two parameters (creating a new rep) should be:

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

And it could also be useful to use the parameter bitmapFormat which says if the components of a pixel are RGB or BGR and where the alpha value is (or the padding byte).

Maybe it should better to use a copy-method?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top