有没有办法在C ++中颠倒数组的顺序?

时间:2015-03-03 22:03:05

标签: c++

我正在制作一个带有.ppm文件的小型照片程序,然后应用滤镜,例如否定红色,绿色,蓝色,水平翻转和灰度(用户选择要应用的滤镜)。除了我在水平翻转时遇到困难,我想出了一切。我认为没有必要发布整个程序,因为我只是在制作一个函数时遇到困难。但是,如果需要,请告诉我,然后我会发布。

以下是取消红色,绿色和蓝色的示例函数。

void negate_red(int image[], int w, int h)
{
    for(int i = 0; i<h; i++)
        for(int j=0; j<w; j++)
    {
        image[(i*w+j)*3] = 255 - image[(i*w+j)*3];
    }
}

void negate_green(int image[], int w, int h)
{
    for(int i = 0; i<h; i++)
        for(int j=0; j<w; j++)
    {
        image[(i*w+j)*3+1] = 255 - image[(i*w+j)*3+1];
    }
}

void negate_blue(int image[], int w, int h)
{
    for(int i = 0; i<h; i++)
        for(int j=0; j<w; j++)
    {
        image[(i*w+j)*3+2] = 255 - image[(i*w+j)*3+2];
    }
}

据我了解,为了水平翻转图像,你必须颠倒数组的顺序。例如,第一个RGB值将是最后一个,对吗?有没有办法扭转数组的顺序?在我问这个问题之前我做了一些搜索,我发现了这个: Correct flip/mirror of pixels of an image?

因此,如果我正确地解释这一点,我应该启动这样的函数:

void flip (int image[], int w, int h)
{
for(int i = 0; i<h/2; i++)
     for(int j=0; j<w/2; j++)
  {
  //code
  }
}

现在有没有办法扭转数组的顺序,让它从最后一个元素开始,然后转到第一个元素?

感谢任何帮助,非常感谢!谢谢!

3 个答案:

答案 0 :(得分:4)

我会从<algorithm>推荐std::reverse()。您可以通过使用(arr, arr+size)调用数组来将数组传递给它。它将反转数组。

为了解决下面的讨论:虽然在一个非常规C语言中将RGB值表示为3个独立整数有点奇怪,但对于OP来说这应该不是问题:确保数组的大小是3的倍数,定义这样的结构:

struct rgb_value {
    int red;
    int green;
    int blue;
};

然后将数组转换为struct rgb_value,并使用(cast_array,cast_array + original_size / 3)调用reverse。这样就可以保持结构内部的顺序。

我有点不喜欢自己做这样的演员表的想法,但是替代方法是编写一个自己的反向函数,它可以保持rgb-order的交换,或者将数据复制到数据结构,其中rgb值如此表示并正确交换。

编辑2:首先我想指出,这不是“如何水平翻转图像?”的答案,而是“有没有办法在C ++中颠倒数组的顺序? ?”。因此,我试图避免OP的图像翻转算法是否尽可能正确以保持主题的问题。

其次,即使假设OP的算法本来是错误的,反向也是选择的算法。其他解决方案提出的建议只不过是一种相当复杂的说法:

rgb_color *pos = reinterpret_cast<rbg_color *>(image);
for (int i = 0; i < num_rows; ++i){
    pos += i * rgb_per_row //select row
    std::reverse(pos, pos + rgb_per_row);//reverse row
} 

rgb_per_row是一行的长度除以sizeof(rgb_value)/sizeof(int)

答案 1 :(得分:4)

您需要遍历图像左侧的每个像素,并将其与右侧的相应像素一起翻转。这意味着您需要查看整个图像中的每一行,但只能走到该行的中间位置。

void swap_int (int *a, int *b)
{
    int temp = *b;
    *b = *a;
    *a = temp;
}

void h_flip (int image[], int w, int h)
{
    for(int i = 0; i<h; i++) // every row
         for(int j=0; j<w/2; j+=3) // halfway through the row
      {
          // We now swap this pixel (i,j) with its mirror pixel
          // on the right (i,w-j), swapping red, green, and blue values
          swap_int (&image [(i*w + j) * 3 + 0], &image [(i*w + (w-j)) * 3 + 0]);
          swap_int (&image [(i*w + j) * 3 + 1], &image [(i*w + (w-j)) * 3 + 1]);
          swap_int (&image [(i*w + j) * 3 + 2], &image [(i*w + (w-j)) * 3 + 2]);
      }
}

答案 2 :(得分:0)

Iterative way:
1) Initialize start and end indexes. 
start = 0, end = n-1
2) In a loop, swap arr[start] with arr[end] and change start and end as follows.
start = start +1; end = end – 1

/* Function to reverse arr[] from start to end*/
void reverseArray(int arr[], int start, int end)
{
  int temp;
  while(start < end)
  {
    temp = arr[start];   
    arr[start] = arr[end];
    arr[end] = temp;
    start++;
    end--;
  }   
}    

尝试将此解决方案应用于您的问题。