简体   繁体   中英

Is there a way to reverse the order of an array in C++?

I am making a small photo program that takes a .ppm file and then applies filters such as negating red, green, blue, flip horizontally, and grey scale (the user selects which filters to apply). I figured everything out except I am having difficulties with the horizontal flip. I do not think it is necessary to post the WHOLE program as I am just experiencing difficulty in making one function. However, if it is required, then please let me know then I will post it.

Here are the sample functions that negates red, green, and blue.

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];
    }
}

To my understanding, in order to flip an image horizontally, you have to reverse the order of the array. For example, the first RGB values will be the last, correct? Is there a way to reverse the order of an array? I did some search before I asked this question, and I found this: Correct flip/mirror of pixels of an image?

So if I am interpreting this correctly, I should start the function like this:

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
  }
}

Now is there a way to reverse the order of the array to make it start for the last element and go to the first?

Any help is appreciated, and thank you so much! Thanks!

I would recommend std::reverse() from <algorithm> . You can pass an array to it by invoking it with (arr, arr+size) . It will reverse the array.

To address the discussion below: while it is somewhat odd to represent something like an RGB value as 3 independent ints in a language other than plain C, this should not be a problem for OP: Ensure that the size of the array is a multiple of 3, define a struct like this:

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

then cast the array to struct rgb_value, and invoke reverse with (cast_array, cast_array + original_size/3). This way the order inside the structs will be maintained.

I kind of don't like the idea of doing casts like this myself, but the alternatives are to write an own reverse function, which does the swaps maintaining rgb-order, or copying the data to a data-structure, where the rgb-values are represented as such and swapped properly.

Edit 2: First of all I would like to point out, that this is not an answer to "How do you flip an image horizontally?", but to "Is there a way to reverse the order of an array in C++?". Therefor I tried to avoid the issue of whether the OP's image-flipping algorithm was correct as much as possible to stay on topic.

Second, even assuming that OP's algorithm was originally wrong, reverse would be the algorithm of choice. What other solutions suggest is nothing else than a fairly complicated way of saying:

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
} 

with rgb_per_row being that length of a row divided by sizeof(rgb_value)/sizeof(int) ,

You need to loop through each pixel on the left side of the image and flip it with its corresponding pixel on the right side. That means you need to look at each line in the whole image but only go halfway through the line.

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]);
      }
}
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--;
  }   
}    

Try applying this solution to your problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM