0

NSBitmapImageRep を構築するときに「bytesPerRow」がどのように計算されるかを理解したいと思います (私の場合は、フロートの配列をグレースケール ビットマップにマッピングすることから)。

この詳細を明らかにすると、浮動小数点数の配列からバイト配列 (0 ~ 255、符号なし 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 

したがって、Nx が 320 まで 1 ずつ増分的に増加する場合でも、バイト/行が 64 バイトの増分でジャンプすることがわかります (これらの Nx 値のすべてを示したわけではありません)。この議論では、Nx = 320 (最大) は任意であることにも注意してください。

では、バイト配列のメモリの割り当てとマッピングの観点から、「行あたりのバイト数」はどのように第一原理から計算されるのでしょうか? 上記の結果は、単一のスキャンラインからのデータを「ワード」長の境界 (私の MacBook Pro では 64 ビット) に揃えることができるのでしょうか?

これがどのように機能するかを理解するのに苦労しています。

4

1 に答える 1

2

0 を渡すbytesPerRow:ことは、コメントで述べた以上のことを意味します。ドキュメントから:

値 0を渡すと、rowBytesパフォーマンスのために、割り当てられたビットマップ データがパディングされて、ロング ワードまたはより大きな境界に収まる場合があります。…ゼロ以外の値を渡すと、正確な行送りを指定できます。

つまり、一度に 64 バイトずつ増加していることがわかります。これは、AppKit が切り上げを決定した方法だからです。

行あたりのバイト数の最小要件は、はるかに単純です。ピクセルあたりのバイト数に行あたりのピクセルを掛けたものです。それで全部です。

浮動小数点数に基づくビットマップ イメージ表現の場合、sizeof(float) * 8for を渡しbitsPerSample、bytes-per-pixel は になりますsizeof(float) * samplesPerPixel。行あたりのバイト数はそれに続きます。ピクセルあたりのバイト数にピクセル単位の幅を掛けます。

同様に、符号なしバイトでサポートされている場合は、sizeof(unsigned char) * 8for を渡しbitsPerSample、bytes-per-pixel は になりますsizeof(unsigned char) * samplesPerPixel

于 2012-02-05T03:06:04.797 に答える