0

Cでbmp画像を操作するこのプログラムを作成しようとしていますが、これまでのところ、そのように回転させることができました:

 for (row=0; row < rows; row++)
      for (col=0; col < cols; col++) 
        {
          (*new) + rows*col + (rows - row -1) = original + row*cols + col;
        }

ここで: Original = 元の bmp、new = 適用したい回転量に応じた比例サイズの新しい bmp。どちらも bmp へのポインターであり、new はポインターへのポインターです。私は数回計算を行いましたが、実際には時計回りに回転させる必要があるときに反時計回りに回転します.それは1つの問題ですが、時計回りに回転しているように見えるようにするのに十分な時間、反時計回りに反転させることができると思います. 私の質問は次のとおりです。元の bmp イメージからローテーションを数回実行し、それを作成中の新しい bmp イメージにするにはどうすればよいですか。つまり、どうすれば上記の操作を数回実行しても、正しいサイズの入力ファイルと出力ファイルが 1 つしかないということです。他の手順で出力を操作しやすくなるため、ポインターを使用してこれを行いたいと思います。

ありがとうございました。

4

3 に答える 3

0

コードを単純化する 1 つの方法は、ループに沿って歩く 2 つの 2D ベースを定義することです。

オリジナルベース:

  • x0 = 0
  • y0 = 0
  • dx = 1
  • dy = 列

新しい基地

  • x0 = 行 - 1
  • y0 = 0
  • dx = 行
  • ダイ = -1

それらを使用してコードを書き直すのは、はるかに簡単です。また、内側のループから乗算を削除できるという利点もあります。

PIXEL *source = original;
PIXEL *target = new + (rows - 1) + (0 * cols);

int source_di = 1;
int source_dj = cols;

int target_di = rows;
int target_dj = -1;

for (int j = 0; j < rows; ++j) {
    int saved_source = source;
    int saved_target = target;

    for (int i = 0; i < cols; ++i) {
        *target = *source;
        source += source_di;
        target += target_di;
    }

    source = saved_source + source_dj;
    target = saved_target + target_dj;
}
于 2013-11-07T04:17:31.083 に答える
0

行列を使用します。擬似コード:

class Matrix {
    double m11,m12,m21,m22;
};

dest.x = matrix.m11*src.x + matrix.m12*src.y;
dest.y = matrix.m21*src.x + matrix.m22*src.y;

どこx = x - image.width/2 and y = y - image.height/2

http://en.wikipedia.org/wiki/Rotation_matrix#Common_rotations

于 2013-10-20T21:43:04.270 に答える
0

以下のコードは、90 度の倍数による float 配列の回転を示しています。後で float 配列をバイト配列に変換して、結果を検証するためのテスト イメージを生成できるようにしました。私はコードのその部分を含めませんでした。なぜなら、それは要点を混乱させるだけであり、実際にあなたが求めていたものではなかったからです. その部分が必要な場合は、私に知らせてください。

「インプレース」ではなく「アウトオブプレース」でローテーションを行ったことに注意してください。あなたが本当に興味を持っているのは後者だと思いますが、それでも、以下のアプローチはあなたにとって良いスタートになるはずです. インプレース変換に関する追加の議論はここにあります。これは、転置型の操作 (メモリ スワップ) の使用を中心にしていますが、それらの詳細をすべて整理する時間がありませんでした。その部分は残しておきます。 .

n*90 度の反時計回りの回転の場合、変換は次のようになることを思い出してください。

ここに画像の説明を入力

それではもちろん:

ここに画像の説明を入力

ただし、実際のコードでは、配列に負のインデックスを渡さないように、以下のコードに示すように、row' と col' をそれぞれ imageHeight/2 と imageWidth/2 で変換する必要があります。

row_p と col_p を row' and col' と表すと、コードは次のようになります。

// Note:  nX = pixels wide, nY = pixels tall
float *dataVector = // some data source, arbitrary

// Setup the array for the out-of-place transformation:
float *dataVector2 = new float[nX*nY]; 

int n = -2;  // Example: set n = -2 to rotate counter-clockwise 180 deg
for (int row = 0; row < nY; row++) {
    for (int col = 0; col < nX; col++) {
        int row_p = cosf(n*M_PI_2)*(row-nY/2) - sinf(n*M_PI_2)*(col-nX/2) + nY/2;
        int col_p = sinf(n*M_PI_2)*(row-nY/2) + cosf(n*M_PI_2)*(col-nX/2) + nX/2;
        dataVector2[row*nX + col] = dataVector[row_p*nX + col_p];
    }
}

// Later convert float array to image ...

上記のコードでは、回転した座標を使用して元の配列の要素にアクセスし、これらの値を元の行の col 座標にマッピングしていることに注意してください。

dataVector2[row*nX + col] = dataVector[row_p*nX + col_p]; 

この結果、+n の値は時計回りの回転になります。反時計回りの回転が必要な場合は、上記の例に示すように、単に n の負の値、つまり -n をコードに渡します。この効果は、上記の回転行列の非対角項の符号を変更するだけです。

お役に立てれば。

于 2013-11-06T19:16:43.687 に答える