【问题标题】:C - Need help swapping red and green components [closed]C - 需要帮助交换红色和绿色组件[关闭]
【发布时间】:2013-04-12 23:34:53
【问题描述】:

这段代码(我从之前的 Stack Overflow 问题中找到的代码编辑而成)能够接受 ppm 图像的输入并输出相同的图像,但所有颜色都是互补的。在我的作业中,我被要求这样做,然后交换红色和绿色组件(基本上将 img->data[i].red 变成 img->data[i].green ,反之亦然)。但是,我不确定如何去做。我不能只做两个相等的陈述,因为第一个基本上会使第二个无效。我唯一能想到的就是创建一个 PPMImage 类型的临时数组(之前创建的一个结构)。但是,我有点不确定代码和逻辑是如何工作的。

这里是代码。 changecolorPPM 函数中的“for”循环是补色的地方,我很确定需要进行交换。

#include<stdio.h>
#include<stdlib.h>

typedef struct {
     unsigned char red,green,blue;
} pixel_t;

typedef struct {
     int x, y;
     pixel_t *data;
} PPMImage;

#define CREATOR "RPFELGUEIRAS"
#define RGB_COMPONENT_COLOR 255

static PPMImage *readPPM(const char *filename)
{
         char buff[16];
         PPMImage *img;
         FILE *fp;
         int c, rgb_comp_color;
         //open PPM file for reading
         fp = fopen(filename, "rb");
          if (!fp) {
              fprintf(stderr, "Unable to open file '%s'\n", filename);
              exit(1);
         }

     //read image format
     if (!fgets(buff, sizeof(buff), fp)) {
          perror(filename);
          exit(1);
     }

//check the image format
if (buff[0] != 'P' || buff[1] != '6') {
     fprintf(stderr, "Invalid image format (must be 'P6')\n");
     exit(1);
}

//alloc memory form image
img = (PPMImage *)malloc(sizeof(PPMImage));
if (!img) {
     fprintf(stderr, "Unable to allocate memory\n");
     exit(1);
}

//check for comments
c = getc(fp);
while (c == '#') {
while (getc(fp) != '\n') ;
     c = getc(fp);
}

ungetc(c, fp);
//read image size information
if (fscanf(fp, "%d %d", &img->x, &img->y) != 2) {
     fprintf(stderr, "Invalid image size (error loading '%s')\n", filename);
     exit(1);
}

//read rgb component
if (fscanf(fp, "%d", &rgb_comp_color) != 1) {
     fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename);
     exit(1);
}

//check rgb component depth
if (rgb_comp_color!= RGB_COMPONENT_COLOR) {
     fprintf(stderr, "'%s' does not have 8-bits components\n", filename);
     exit(1);
}

while (fgetc(fp) != '\n') ;
//memory allocation for pixel data
img->data = (pixel_t*)malloc(img->x * img->y * sizeof(pixel_t));

if (!img) {
     fprintf(stderr, "Unable to allocate memory\n");
     exit(1);
}

//read pixel data from file
if (fread(img->data, 3 * img->x, img->y, fp) != img->y) {
     fprintf(stderr, "Error loading image '%s'\n", filename);
     exit(1);
}

fclose(fp);
return img;
}
 void writePPM(const char *filename, PPMImage *img)
{
FILE *fp;
//open file for output
fp = fopen(filename, "wb");
if (!fp) {
     fprintf(stderr, "Unable to open file '%s'\n", filename);
     exit(1);
}

//write the header file
//image format
fprintf(fp, "P6\n");

//comments
fprintf(fp, "# Created by %s\n",CREATOR);

//image size
fprintf(fp, "%d %d\n",img->x,img->y);

// rgb component depth
fprintf(fp, "%d\n",RGB_COMPONENT_COLOR);

// pixel data
fwrite(img->data, 3 * img->x, img->y, fp);
fclose(fp);
}

void changeColorPPM(PPMImage *img)
{
int i;

if(img){

     for(i=0;i<img->x*img->y;i++){
          img->data[i].red=RGB_COMPONENT_COLOR-img->data[i].red;
          img->data[i].green=RGB_COMPONENT_COLOR-img->data[i].green;
          img->data[i].blue=RGB_COMPONENT_COLOR-img->data[i].blue;
     }
}
}

int main(int argc, char* argv[]){
PPMImage *image;
char* filename = argv[1];
image = readPPM(filename);
changeColorPPM(image);
writePPM("OutputFile.ppm",image);
printf("Press Enter");
getchar();
}

【问题讨论】:

  • 搜索“交换 C 中的两个值”。
  • 我不喜欢这个。你有一个任务,你只是复制粘贴它。它在很多层上都很糟糕......但这就是你需要的:创建临时变量int t 来存储img-&gt;data[i].red,然后将red 设置为green,然后将green 设置为t
  • 即使 img->data[i].red/green 需要是一个数组,这也可以工作?

标签: c struct ppm


【解决方案1】:

根据您的问题,我相信您正在寻找可以轻松实现为的swap 函数

img->data[i].red = img->data[i].red + img->data[i].green;
img->data[i].green = img->data[i].red - img->data[i].green;
img->data[i].red = img->data[i].red - img->data[i].green;

更新:

如果加法操作没有溢出,则此部分很好。但是,如果目标的精度不足以容纳位,则可能会丢失数据。因此,在这些情况下,正如 Mats 和其他专家所建议的那样,传统的临时变量方法将是最好的前进方式

temp = img->data[i].red;
img->data[i].red = img->data[i].green;
img->data[i].green = temp;

注意:

如果您从事图像处理,那么从视觉角度来看,这种交换可能并不令人愉悦。通常,绿色包含最大强度,即与红色和蓝色相比的亮度信息量,人眼可以很容易地捕捉到强度的变化。检查一下交换后最终图片的样子会很有趣。

【讨论】:

  • 啊,我可以在这里看到你的逻辑。更不用说,这在许多其他情况下也可以派上用场。老实说,我从来没有,即使它可能是那么简单的哈哈。非常感谢!
  • @Austin .. 很好.. 请检查我的更新答案,并在最后附上注释。这可能很有趣:)
  • 这不太可能比通常编写的t = img-&gt;data[i].red; img-&gt;data[i].red = img-&gt;data[i].green; img-&gt;data[i].green = t;" - this is how a normal swap 函数更有效。
  • @Ganesh 我实现了你的功能,它看起来好像没有做任何过于激烈的事情。我使用了我为另一项任务制作的爱尔兰国旗的 ppm 图像。它从浅绿色变成粉红色,从白色变成黑色,从浅橙色变成浅蓝色。再次感谢!
  • 是的,我关心的是性能,而不是“它实际上做了什么”。并且白色不应该从去除绿色到黑色。它应该变成紫色 - 你可能做错了什么......
猜你喜欢
  • 2013-05-02
  • 2014-08-26
  • 1970-01-01
  • 1970-01-01
  • 2011-09-15
  • 2014-08-31
  • 1970-01-01
  • 1970-01-01
  • 2018-11-10
相关资源
最近更新 更多