2 次元画像 (または可変サイズの任意の 2 次元行列) を格納してアクセスする通常の方法は、適切なサイズの 1 次元配列 ( width * height
、または(width + padding) * height
) を割り当て、配列へのインデックスを「手動で」計算することです ( y * stride + x
、どこにstride
ありますwidth + padding
)。
(私は通常std::vector
、その1次元配列に使用しますが、それは別の話です)
2D 画像データを参照する通常の方法 (参照渡しの参照) は、次のタプルを渡すことです。
void* imageData
-- 左上のピクセルのアドレス
size_t stride
imageData
--次の行に移動するために追加するバイト数
size_t width
size_t height
SomeEnum pixelFormat
-- 画像のピクセル形式 (1 つしかない場合は省略可能)
もちろん、Pixel-Format が 1 つしかない場合は、型指定されたポインターを使用して、stride
(バイトではなく) その型の単位で指定できます。
このような参照を使用すると、ループ内のピクセルに非常に簡単かつ効率的にアクセスできます。
size_t const bytesPerPixel = GetBytesPerPixel(ref->pixelFormat);
for (size_t y = 0; y < ref->height; y++)
{
unsigned char* currentLine =
static_cast<unsigned char*>(ref->imageData) + ref->stride * y;
for (size_t x = 0; x < ref->width; x++)
{
// any modern compiler will optimize the multiplication below to
// an incremental addition
unsigned char* currentPixel = currentLine + bytesPerPixel * y;
// do something to the pixel data at
// currentPixel[0] ... currentPixel[bytesPerPixel - 1]
}
}
このように画像参照を渡すことの良い点は、そのような参照を元の画像のサブ矩形を指すようにいつでも「調整」できることです。それに応じて値を調整する必要があります。imageData
サブ四角形の左上のピクセルをポイントして、サブ四角形の幅と高さを設定width
します。同じままです。height
stride
つまり、トリミングされた画像を「実体化」する必要はなく、サブ矩形への参照を任意の関数に渡すだけで、「完全な」画像と同じようにそのサブ矩形で動作します。
また、切り抜いた画像を本当に「具現化」したい場合は、それを行うのに十分な情報が必要です。少なくとも私はそう願っています:)
編集:あなたは sf::IntRect 部分について非常に明示的でしたが、sf::Image の代わりに「画像」としか書いていなかったので、sf::Image ではなく、自分で管理するものについて話していると思いました。良い...
sf::Image のサブレクトを別の sf::Image にコピーしたいだけなら、次のようにできます:
sf::Image sourceImage = ...;
sf::IntRect subRect = ...;
// construct an empty sf::Image with the appropriate dimensions
sf::Image newImage(subRect.GetWidth(), subRect.GetHeight());
// copy the pixel data into the new image
newImage.Copy(sourceImage, 0, 0, subRect);