C++ 无法翻转 ppm 图像
C++ trouble flipping a ppm image
我成功地找到了如何从 ppm 文件中读取 rgb 值,现在我需要修改它。然而,当我翻转图像时(readImg 中的第二组 for 循环),它显示完全相同的图像。这是否与数组是无符号字符有关,还是它仍在输入流中。任何帮助都会很棒。
#include "finalproj.h"
int readImg(std::string header, unsigned char r[][HEIGHT], unsigned char g[][HEIGHT], unsigned char b[][HEIGHT])
{
int wid, hei, max;
int j= wid/2;
int k= hei/2;
std::ifstream fin;
fin.open("cs1a.ppm");
fin >> header;
fin >> wid >> hei >> max;
for(int col=0; col < wid; ++col)
{
for(int row=0; row < hei; ++row)
{
r[col][row] = fin.get();
g[col][row] = fin.get();
b[col][row] = fin.get();
}
}
for(int col=0; col < wid; ++col)
{
--k;
for(int row = hei/2; row < hei/2; ++row)
{
--j;
r[col][row] =r[j][k];
g[col][row] =g[j][k];
b[col][row] =b[j][k];
}
}
// mirrorHoriz(header, wid, hei, max, r, g, b);
saveImg(header, wid, hei, max, r,g,b);
fin.close();
return 0;
}
~
~
#include "finalproj.h"
int saveImg(std::string header, int wid, int hei, int max, unsigned char r[][HEIGHT], unsigned char g[][HEIGHT], unsigned char b[][HEIGHT])
{
std::ofstream fout;
fout.open("new.ppm");
fout << header << std::endl;
fout << wid << " " << hei << std::endl;
fout << max << std::endl;
for(int col=0; col < wid; ++col)
{
for(int row=0; row < hei; ++row)
{
fout << g[col][row];
fout << b[col][row];
fout << r[col][row];
}
}
fout.close();
return 0;
}
~
~
#include "finalproj.h"
int main()
{
int wid, hei, max;
unsigned char r[WID][HEIGHT], g[WID][HEIGHT], b[WID][HEIGHT];
std::string header;
readImg(header, r, g ,b);
return 0;
}
要创建关于 x 轴的镜像 readImg(...)
应该如下所示:
if (hei >= 2)
{
unsigned char tmp;
for (int col=0; (col < wid); ++col)
{
for(int row=hei/2, k=row; ((k >= 0) && (row < hei)); ++row, --k)
{
tmp=r[col][row]; r[col][row]=r[col][k]; r[col][k]=tmp;
tmp=g[col][row]; g[col][row]=g[col][k]; g[col][k]=tmp;
tmp=b[col][row]; b[col][row]=b[col][k]; b[col][k]=tmp;
//// same as
//std::swap(r[col][row], r[col][k]);
//std::swap(g[col][row], g[col][k]);
//std::swap(b[col][row], b[col][k]);
}
}
}
上述方法从图像的中心开始,并在向边缘移动的同时交换行数据。此方法仅在 ((hei % 2) == 1)
.
时有效
推荐的方法是从边缘开始;向中心移动时交换顶部和底部行数据:
如果您更喜欢使用索引
if (hei >= 2)
{
for (int col=0; (col < wid); ++col)
{
int i = 0; // top
int j = (hei - 1); // bottom
while (i < j) // swap top and bottom row data progressively
{
std::swap(r[col][i], r[col][j]);
std::swap(g[col][i], g[col][j]);
std::swap(b[col][i], b[col][j]); ++i; --j;
}
}
}
如果您更喜欢使用指针:
if (hei >= 2)
{
for (int col=0; (col < wid); ++col)
{
unsigned char *r0 = &r[col][0];
unsigned char *r1 = &r[col][hei - 1];
unsigned char *g0 = &g[col][0];
unsigned char *g1 = &g[col][hei - 1];
unsigned char *b0 = &b[col][0];
unsigned char *b1 = &b[col][hei - 1];
while (r0 < r1)
{
std::swap(*r0, *r1); ++r0; --r1;
std::swap(*g0, *g1); ++g0; --g1;
std::swap(*b0, *b1); ++b0; --b1;
}
}
}
我成功地找到了如何从 ppm 文件中读取 rgb 值,现在我需要修改它。然而,当我翻转图像时(readImg 中的第二组 for 循环),它显示完全相同的图像。这是否与数组是无符号字符有关,还是它仍在输入流中。任何帮助都会很棒。
#include "finalproj.h"
int readImg(std::string header, unsigned char r[][HEIGHT], unsigned char g[][HEIGHT], unsigned char b[][HEIGHT])
{
int wid, hei, max;
int j= wid/2;
int k= hei/2;
std::ifstream fin;
fin.open("cs1a.ppm");
fin >> header;
fin >> wid >> hei >> max;
for(int col=0; col < wid; ++col)
{
for(int row=0; row < hei; ++row)
{
r[col][row] = fin.get();
g[col][row] = fin.get();
b[col][row] = fin.get();
}
}
for(int col=0; col < wid; ++col)
{
--k;
for(int row = hei/2; row < hei/2; ++row)
{
--j;
r[col][row] =r[j][k];
g[col][row] =g[j][k];
b[col][row] =b[j][k];
}
}
// mirrorHoriz(header, wid, hei, max, r, g, b);
saveImg(header, wid, hei, max, r,g,b);
fin.close();
return 0;
}
~ ~
#include "finalproj.h"
int saveImg(std::string header, int wid, int hei, int max, unsigned char r[][HEIGHT], unsigned char g[][HEIGHT], unsigned char b[][HEIGHT])
{
std::ofstream fout;
fout.open("new.ppm");
fout << header << std::endl;
fout << wid << " " << hei << std::endl;
fout << max << std::endl;
for(int col=0; col < wid; ++col)
{
for(int row=0; row < hei; ++row)
{
fout << g[col][row];
fout << b[col][row];
fout << r[col][row];
}
}
fout.close();
return 0;
}
~
~
#include "finalproj.h"
int main()
{
int wid, hei, max;
unsigned char r[WID][HEIGHT], g[WID][HEIGHT], b[WID][HEIGHT];
std::string header;
readImg(header, r, g ,b);
return 0;
}
要创建关于 x 轴的镜像 readImg(...)
应该如下所示:
if (hei >= 2)
{
unsigned char tmp;
for (int col=0; (col < wid); ++col)
{
for(int row=hei/2, k=row; ((k >= 0) && (row < hei)); ++row, --k)
{
tmp=r[col][row]; r[col][row]=r[col][k]; r[col][k]=tmp;
tmp=g[col][row]; g[col][row]=g[col][k]; g[col][k]=tmp;
tmp=b[col][row]; b[col][row]=b[col][k]; b[col][k]=tmp;
//// same as
//std::swap(r[col][row], r[col][k]);
//std::swap(g[col][row], g[col][k]);
//std::swap(b[col][row], b[col][k]);
}
}
}
上述方法从图像的中心开始,并在向边缘移动的同时交换行数据。此方法仅在 ((hei % 2) == 1)
.
推荐的方法是从边缘开始;向中心移动时交换顶部和底部行数据:
如果您更喜欢使用索引
if (hei >= 2)
{
for (int col=0; (col < wid); ++col)
{
int i = 0; // top
int j = (hei - 1); // bottom
while (i < j) // swap top and bottom row data progressively
{
std::swap(r[col][i], r[col][j]);
std::swap(g[col][i], g[col][j]);
std::swap(b[col][i], b[col][j]); ++i; --j;
}
}
}
如果您更喜欢使用指针:
if (hei >= 2)
{
for (int col=0; (col < wid); ++col)
{
unsigned char *r0 = &r[col][0];
unsigned char *r1 = &r[col][hei - 1];
unsigned char *g0 = &g[col][0];
unsigned char *g1 = &g[col][hei - 1];
unsigned char *b0 = &b[col][0];
unsigned char *b1 = &b[col][hei - 1];
while (r0 < r1)
{
std::swap(*r0, *r1); ++r0; --r1;
std::swap(*g0, *g1); ++g0; --g1;
std::swap(*b0, *b1); ++b0; --b1;
}
}
}