2012-02-05 4 views
0

Я хотел бы понять, как вычисляется «bytesPerRow» при создании NSBitmapImageRep (в моем случае из сопоставления массива поплавков в растровое изображение в градациях серого).Как «bytesPerRow» вычисляется из NSBitmapImageRep

Уточнение этой детали поможет мне понять, как память отображается из массива поплавков в массив байтов (0-255, unsigned char, ни один из этих массивов не показан в приведенном ниже коде).

В документации Apple говорится, что это число рассчитывается «по ширине изображения, количеству бит в выборке и, если данные находятся в сетчатой ​​конфигурации, количество выборок на пиксель».

У меня была проблема после этого «расчета», поэтому я настраиваю простой цикл, чтобы найти результаты эмпирически. Следующий код работает просто отлично:

int Ny = 1; // Ny is arbitrary, note that BytesPerPlane is calculated as we would expect = Ny*BytesPerRow; 
for (int Nx = 0; Nx<320; Nx+=64) { 
    // greyscale image representation: 
    NSBitmapImageRep *dataBitMapRep = [[NSBitmapImageRep alloc] 
     initWithBitmapDataPlanes: nil // allocate the pixel buffer for us 
     pixelsWide: Nx 
     pixelsHigh: Ny 
     bitsPerSample: 8 
     samplesPerPixel: 1 
     hasAlpha: NO 
     isPlanar: NO 
     colorSpaceName: NSCalibratedWhiteColorSpace // 0 = black, 1 = white 
     bytesPerRow: 0 // 0 means "you figure it out" 
     bitsPerPixel: 8]; // bitsPerSample must agree with samplesPerPixel 
    long rowBytes = [dataBitMapRep bytesPerRow]; 
    printf("Nx = %d; bytes per row = %lu \n",Nx, rowBytes); 
} 

и выдает результат:

Nx = 0; bytes per row = 0 
Nx = 64; bytes per row = 64 
Nx = 128; bytes per row = 128 
Nx = 192; bytes per row = 192 
Nx = 256; bytes per row = 256 

Таким образом, мы видим, что/строка байтов перескакивает с шагом 64 байта, даже если Nx постепенно увеличивается на 1 все пути до 320 (я не показывал все эти значения Nx). Заметим также, что Nx = 320 (max) произвольно для этого обсуждения.

Итак, с точки зрения выделения и сопоставления памяти для байтового массива, как «байты на строку» вычисляются из первых принципов? Является ли результат выше, поэтому данные из одной строки сканирования могут быть выровнены на границе слова «длина слова» (64 бит на моем MacBook Pro)?

Благодарим за понимание, возникшие проблемы с изображением того, как это работает.

+0

Будьте осторожны, чтобы не путать 64 * байты * с 64 * битами *. –

+0

Да, спасибо, я, кажется, много чего делаю. –

ответ

2

Передача 0 для bytesPerRow: означает больше, чем вы сказали в вашем комментарии. Из документации:

Если вы передаете в rowBytes значение 0, данные растрового изображения, выделенные может быть дополнен, чтобы упасть на длинное слово или большие границы для выполнения. ... Передача ненулевого значения позволяет вам указать точные строки.

Таким образом, вы видите, что он увеличивается на 64 байта за раз, потому что именно так AppKit решил округлить его.

Минимальное требование для байтов в строке намного проще. Это байты на пиксель раз пикселей в строке. Это все.

Для изображения растрового изображения, поддерживаемого поплавками, вы должны передать sizeof(float) * 8 для bitsPerSample, а байтами на пиксель будет sizeof(float) * samplesPerPixel. Из этого следует байт за строку; вы умножаете байты на пиксель на ширину в пикселях.

Аналогичным образом, если он поддерживается беззнаковыми байтами, вы должны передать sizeof(unsigned char) * 8 для bitsPerSample, а байты на пиксель будут sizeof(unsigned char) * samplesPerPixel.

+0

Привет, Питер, спасибо за ваши уточняющие комментарии. Для моего приложения я использую последнее (подкрепленное беззнаковыми байтами), так что bitsPerSample = 1 * 8 = 8 и bytesPerPixel = 1 * 8 = 8, как в моем коде выше, и это работает отлично (изображения отображаются в порядке). Я просто не мог рассчитать с первых принципов, как AppKit достигает своих значений для BytesPerRow и, следовательно, не может сказать, что я это понимаю. Я получаю BytesPerRow = Nx * bytesPerPixel = 320 * 8 = 2560, кажется огромным по сравнению с Appkit (= 320).Итак, я пытался выяснить, откуда пришли 320, и, кроме того, есть ли преимущество в использовании 2560? Еще раз спасибо. –

+0

@BruceDean: Вы умножаетесь на 8 раз, чем должны. Учитывая 8 бит (_ = 1 byte_) на образец и 1 образец на пиксель, это 1 байт на пиксель, а не 8. –

+0

Спасибо, ваше право! Цените свои комментарии по этому поводу. –

Смежные вопросы