我正在制作一个带有.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
}
}
现在有没有办法扭转数组的顺序,让它从最后一个元素开始,然后转到第一个元素?
感谢任何帮助,非常感谢!谢谢!
答案 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--;
}
}
尝试将此解决方案应用于您的问题。