我的功能是获取图像,我正试图展示它的镜像。 水平翻转。我尝试做像交换功能这样的东西,但它打印出原始图片。
图像的大小为m * n,函数知道m和n的值。
这是我的代码:
void flipfunc(Img *img)
{
int y;
int x;
const int middleX = m / 2;
char tmp;
char* p;
for (x = 0; x < middleX; ++x)
{
p = image->data + x * m;
for (y = 0; y <3*n; y+=3)
{
// swap pixels
tmp = p[y];
p[y] = p[3*n - 1 - y];
p[3*n - 1 - y] = tmp;
tmp = p[y+1];
p[y+1] = p[3*n - 1 - (y+1)];
p[3*n - 1 - y] = tmp;
tmp = p[y+2];
p[y+2] = p[3*n - 1 - (y+2)];
p[3*n - 1 - (y+2)] = tmp;
}
}
}
/ *图像类型 - 包含高度,宽度和RGB数据* /
struct Img {
unsigned long X;
unsigned long Y;
char *data;
};
答案 0 :(得分:1)
暂且不谈评论中提到的其他问题,我会尝试回答一些提示:
1)在您的函数中,您希望对给定的rgb图像进行就地镜像。这是合理的。
2)你正在考虑使用“middleX”和像素交换方法正确的方向。但是看起来你做错了:你完全忽略了图像的上半部分,而是将下半部分的每一行交换两次!这就是为什么你最终会得到相同的图像。那你为什么不把你的“中间”逻辑应用到内部循环而不是外部循环?
答案 1 :(得分:0)
图像通常以行主光栅顺序存储。也就是说,第一行的所有像素都来自(=它们的地址小于)第二行,第三行等的像素。
要显示宽度为5且高度为4的示例图像:
RGB RGB RGB RGB RGB
RGB RGB RGB RGB RGB
RGB RGB RGB RGB RGB
RGB RGB RGB RGB RGB
每个字母代表内存中的一个字节;空间只是为了清晰起见。
要在图像中查找特定样本,您必须进行一些算术运算。例如,找到x {1且y = 2的G
像素样本。我用大写字母G标记了它:
,,, ,,, ,,, ,,, ,,,
,,, ,,, ,,, ,,, ,,,
,,, ,G. ... ... ...
... ... ... ... ...
要在data
数组中找到它的偏移量,请计算它前面的样本数(我用,
标记它们)。如果你足够捣蛋,你可以发现这个公式:
offset = y * 3 * sizeX + x * 3 + k;
其中k
为0
,1
或2
,具体取决于您要查找的颜色。
您的代码有(例如)
x * m + y
这根本不正确。
顺便说一下,你不应该使用m
或n
之类的变量名称 - 它们非常令人困惑。只需使用
image->sizeX
或者,如果你想使用临时变量:
unsigned long sizeX = image->sizeX;
答案 2 :(得分:0)
这应该有效:
void flipfunc(Img *img)
{
int y;
int x;
int l, r;
char tmp;
for (y = 0; y < img->y; ++ y) {
for (l = 0, r = img->x - 1; l < r; ++ l, -- r) {
for (d = 0; d < 3; ++ d) {
tmp = img->data[(y * img->x + l) * 3 + d];
img->data[(y * img->x + l) * 3 + d] = img->data[(y * img->x + r) * 3 + d];
img->data[(y * img->x + r) * 3 + d] = tmp;
}
}
}
}
如果你想要某些东西,让我们说,更优化,用-O2构建它。