2013-10-20 60 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; 
}