NSBitmapImageRep bug

Этот код производит очень странный вывод. Зачем? Все, что я делаю, это копирую изображение.

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

Пример:

нормальныйсломанный

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 и где находится значение альфа (или байт заполнения).

Может быть, лучше использовать copy-метод?

Другие вопросы по тегам