1

ねえ、私は画像参照と sf::IntRect を受け取る関数を作ろうとしています

(これには、長方形の上、下、左、および右の辺を表す 4 つの int があります。この長方形は、表示されている画像の一部を表しますが、実際には長方形の外側のピクセルを切り捨てません)。

次に、IntRect の外側のピクセルを切り取って、新しい圧縮イメージを作成します。これを行う唯一の方法は、IntRect と同じ寸法の 2D ピクセル配列を作成し、画像を反復処理してそれを埋めることだと考えましたが、IntRect の寸法がわからないため、定数を作成できません配列......

この問題は継続的に発生します。一連のベクトル作業と c_style 配列への変換を行うと、パフォーマンスが大幅に低下すると思います..

画像のサイズと色を大幅に操作/変更するための簡単な解決策はありますか?

4

1 に答える 1

1

2 次元画像 (または可変サイズの任意の 2 次元行列) を格納してアクセスする通常の方法は、適切なサイズの 1 次元配列 ( width * height、または(width + padding) * height) を割り当て、配列へのインデックスを「手動で」計算することです ( y * stride + x、どこにstrideありますwidth + padding)。

(私は通常std::vector、その1次元配列に使用しますが、それは別の話です)

2D 画像データを参照する通常の方法 (参照渡しの参照) は、次のタプルを渡すことです。

  • void* imageData-- 左上のピクセルのアドレス
  • size_t strideimageData--次の行に移動するために追加するバイト数
  • 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します。同じままです。heightstride

つまり、トリミングされた画像を「実体化」する必要はなく、サブ矩形への参照を任意の関数に渡すだけで、「完全な」画像と同じようにそのサブ矩形で動作します。

また、切り抜いた画像を本当に「具現化」したい場合は、それを行うのに十分な情報が必要です。少なくとも私はそう願っています:)

編集:あなたは 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);
于 2011-06-15T01:17:04.933 に答える