是否有一种方法可以在C++中反转数组的顺序?
我正在制作一个小的照片程序,它拍摄一个.ppm文件,然后应用一些滤镜,例如,对红色、绿色、蓝色、水平翻转和灰度进行消噪,用户选择应用哪些滤镜。我把一切都弄清楚了,除了我在水平翻转方面有困难。我不认为有必要发布整个程序,因为我只是在制作一个函数时遇到了困难。然而,如果它是必需的,那么请让我知道,然后我会张贴它 下面是否定红色、绿色和蓝色的示例函数是否有一种方法可以在C++中反转数组的顺序?,c++,C++,我正在制作一个小的照片程序,它拍摄一个.ppm文件,然后应用一些滤镜,例如,对红色、绿色、蓝色、水平翻转和灰度进行消噪,用户选择应用哪些滤镜。我把一切都弄清楚了,除了我在水平翻转方面有困难。我不认为有必要发布整个程序,因为我只是在制作一个函数时遇到了困难。然而,如果它是必需的,那么请让我知道,然后我会张贴它 下面是否定红色、绿色和蓝色的示例函数 void negate_red(int image[], int w, int h) { for(int i = 0; i<h; i++)
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值将是最后一个,对吗?有没有办法反转数组的顺序?在我问这个问题之前,我做了一些搜索,我发现:
因此,如果我正确解释了这一点,我应该像这样启动函数:
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
}
}
struct rgb_value {
int red;
int green;
int blue;
};
现在有没有办法反转数组的顺序,使其从最后一个元素开始,然后转到第一个元素
非常感谢您的帮助,非常感谢!谢谢 我会推荐你。您可以通过使用arr、arr+size调用它来将数组传递给它。它将反转阵列
为了解决下面的讨论:虽然在非纯C语言中将RGB值表示为3个独立整数有些奇怪,但这对OP来说应该不是问题:确保数组的大小是3的倍数,定义如下结构:
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
}
}
struct rgb_value {
int red;
int green;
int blue;
};
然后将数组强制转换为struct rgb_值,并使用强制转换数组调用reverse,强制转换数组+原始大小/3。这样,结构内部的顺序将得到维护
我有点不喜欢自己做这种类型转换的想法,但替代方法是编写自己的反向函数,该函数执行保持rgb顺序的交换,或者将数据复制到数据结构中,其中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_等于行的长度除以sizeofrgb_值/sizeofint
尝试将此解决方案应用于您的问题 您需要在图像左侧的每个像素之间循环,并将其与右侧相应的像素翻转。这意味着您需要查看整个图像中的每一行,但只需查看该行的一半
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]);
}
}
“是的,有办法。”阿尔莫史诗般的回答。太棒了,我需要澄清一下。你是怎么看这张照片的?您是否一次读取4个字节,将单个RGB三元组读取为一个整数?或者你把R读入一个int,把G读入下一个int,把B读入最后一个int?所有的东西都有一个标准算法。这会反转RGB值,不是吗?它会反转数组中项目的顺序。它不会反转数组中存储的值的字节顺序。第一项将成为最后一项,最后一项将成为第一项。@BenKey Right。考虑到RGB三元组将占用一个int的空间,这是有道理的。出于某种原因,我考虑使用char。但反转一维阵列不会沿一个轴镜像图像。它会在两个方向上翻转吗?@BenKey:Chris是对的。如果您查看Aaron的代码,您将看到每个RGB值都存储在一个int中,而图像是一个int数组。因此,如果你反转一条线对应的数组,你不仅会水平翻转图片,还会交换颜色。R1G1B1_R2G2B2一旦恢复,将提供B2G2R2_B1G1R1,但您需要的是R2G2B2_R1G1B1。红色和蓝色可以互换,而绿色部分是正确的。这是唯一一个似乎意识到图像是2D而不是1D的答案。@DavidSchwartz但如果这样做,就不会互换像素!您仅修改图像的左半部分。右半部分将保持不变。基本上,如果原始行类似于abcd,您需要的是dcba。您的代码将提供dccd。换句话说,你所做的是镜像右半部分,而不是翻转整个画面。