2013-10-20 59 views
0

我試圖寫這個程序,操縱BMP圖像C和到目前爲止,我已經成功地將其旋轉這樣:如何以C爲增量旋轉90度的bmp圖像?

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

其中:原始=原始BMP,適度規模的新=新的BMP取決於我想要應用的旋轉量。兩者都是指向bmp的指針,new是指向指針的指針。 我已經做了好幾次數學運算,並且當它順時針旋轉時,它會逆時針旋轉。這是一個問題,但是我想我可以逆時針翻轉它,讓它看起來順時針旋轉。我的問題是:我將如何從原始bmp圖像進行幾次旋轉,並最終創建新的bmp圖像。 也就是說,如何執行上述操作多次,仍然只有1個輸入和1個正確大小的輸出文件。 我想用指針來做這件事,因爲它會讓我更容易操作其他過程中的輸出。 我希望這是足夠的細節。

謝謝。

+0

我建議你在方格紙上做一個簡單的矩形,然後在矩形中用正方形的數字填充正方形。然後你「旋轉」那個矩形。這樣你會看到它其實很簡單。 –

+0

對,我已經完成了這個工作,並得到了旋轉的工作方式。我的問題實際上並不是在旋轉它,而是如何做幾次。我不得不爲每一次迭代創建新的指針,而且我不確定如何去做幾次,如果我想實現這個目標,我必須多次創建一個新的指針, 270度旋轉。 – user2824512

+0

這是一樣的。例如,旋轉180度實際上比旋轉90度更簡單。所以對於一個270度的旋轉,做一個180和一個90.你只需要兩個「指針」,源和目標位圖,這兩個都是同樣大(除了90和270度的寬度和高度開關位置)。 –

回答

0

下面的代碼由90度的倍數演示了一個浮陣列的旋轉。我後來將float數組轉換爲一個字節數組,以便我可以生成測試圖像來驗證結果;我沒有包含代碼的那部分內容,因爲它只是混淆了主要觀點,實際上並不是你詢問的內容。如果你需要那部分,讓我知道我會發布它。

請注意,我做了「不在位」的輪換,而不是「在原地」。我相信後者就是你真正感興趣的東西,但即使如此,下面的方法對你來說應該是一個好的開始。關於就地轉換的其他討論可以是found here,它圍繞使用轉置類型操作(內存交換),但我沒有時間對所有這些細節進行分類,我將爲你留下那部分內容。

enter image description here

當然這樣看來:

enter image description here

但在

回想一下,對於N * 90度逆時針旋轉,變換由下式給出實際代碼需要分別通過imageHeight/2和imageWidth/2來轉換行'和col',如下面的代碼所示,以避免將負向索引傳遞到您的數組。

表示row_p和col_p作爲行「和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)傳遞給您的代碼,如上例所示。這樣做的效果是僅改變上面旋轉矩陣的非對角線項的符號。

希望這會有所幫助。

0

一個簡化代碼的方法是定義你會沿着你的循環行走兩個2D基地:

原始基礎:

  • X0 = 0
  • Y0 = 0
  • DX = 1
  • DY = COLS

新基地

  • X0 =行 - 1個
  • Y0 = 0
  • DX =行
  • DY = -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; 
}