2013-04-12 6 views
-3

Ce code (que j'ai édité à partir d'un code trouvé sur une précédente question Stack Overflow) peut prendre l'entrée d'une image ppm et sortir la même image, mais avec tous les couleurs complémentaires. Dans mon devoir, on me demande de le faire, mais ensuite d'échanger les composantes rouge et verte (en gros, img-> data [i] .red en img-> data [i] .green et vice versa). Cependant, je ne suis pas sûr de la façon de le faire. Je ne peux pas faire deux déclarations égales, car la première annulerait essentiellement la seconde. La seule chose à laquelle je peux penser est de créer un tableau temporaire du type PPMImage (une structure créée plus tôt). Cependant, je suis un peu incertain de la façon dont le code et la logique pour cela fonctionneraient.C - Besoin d'aide pour changer les composants rouges et verts

Voici le code. La boucle 'for' dans la fonction changecolorPPM est l'endroit où les couleurs sont complétées, et où je suis assez sûr que le swap doit se produire.

#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(); 
} 
+0

Rechercher "échanger deux valeurs en C". –

+2

Je n'aime pas ça. Vous avez une mission et vous ne faites que copier-coller. C'est mauvais sur autant de couches ... Mais voici ce dont vous avez besoin: créer une variable temporaire int int pour stocker 'img-> data [i] .red' puis mettre' red' à 'green' puis' green 'à' t'. –

+0

Cela fonctionnerait même si img-> data [i] .red/green doit être un tableau? – Austin

Répondre

0

De votre question, je crois que vous êtes à la recherche d'une fonction swap qui pourrait facilement être mis en œuvre comme

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; 

Mise à jour:

Cette section est très bien s'il n'y a pas de débordement de l'opération d'addition. Cependant, si la précision de la destination n'est pas suffisante pour contenir les bits, il peut y avoir une perte de données potentielle. Par conséquent, dans ces cas, comme Mats et d'autres experts ont suggéré, la méthode variable temporaire traditionnelle serait la meilleure voie à suivre

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

Note:

Si vous êtes dans le traitement d'image, alors ce swap peut ne pas être agréable d'un point de vue visuel. Habituellement, le vert contient l'intensité maximale, c'est-à-dire la quantité d'informations sur la luminosité, par rapport au rouge et au bleu, et l'œil humain peut facilement saisir les variations d'intensité. Il sera intéressant de vérifier, comment l'image finale ressemble après l'échange.

+0

Ah, je peux voir ta logique ici. Sans oublier que cela pourrait aussi être utile dans beaucoup d'autres situations. Pour être honnête, je n'ai jamais pensé que ce soit aussi simple que ça. Merci beaucoup! – Austin

+0

@Austin .. Nice .. S'il vous plaît vérifier ma réponse mise à jour avec une note à la fin. Cela pourrait être intéressant :) – Ganesh

+3

Il est très peu probable que cela soit plus efficace que 't = img-> data [i] .red; img-> données [i] .red = img-> données [i] .green; img-> data [i] .green = t; "- c'est ainsi que s'écrit typiquement une fonction normale de" swap " –

Questions connexes