Home > OS >  im adding a filter effect on a image and i use this code to achieve it . but i dont understand why m
im adding a filter effect on a image and i use this code to achieve it . but i dont understand why m

Time:07-08

So i wrote this block of code

    void grayscale(int height, int width, RGBTRIPLE image[height][width])
{

 for (int i = 0 ; i < (height) ; i  )
    {
        for(int j = 0 ; j <(width); j   ){
            float blue = image[i][j].rgbtBlue;
            float green = image[i][j].rgbtGreen;
            float red = image[i][j].rgbtRed;
            int average_color = round((blue   green   red) /3);
            image[i][j].rgbtBlue = image[i][j].rgbtGreen = image[i][j].rgbtRed = average_color;
            // red = blue = green = average_color; WHY IS THAT WORNG INSTEAD OF THE LINE ABOVE?
        }
    }
    return;
}

and in the comment i had my first attempt on the code but it didnt get the value of average_color this way?

and only when i tried it like this

            image[i][j].rgbtBlue = image[i][j].rgbtGreen = image[i][j].rgbtRed = average_color;

why red=blu=green=avergae_color; doesnt work?

CodePudding user response:

Lets understand one of your statements

float blue = image[i][j].rgbtBlue;

This statement is a definition in C, i.e. it is a declaration which is then instantiated. A declaration in simple terms, informs the compiler that the given identifier(blue) is associated with the given data type(float). When you assign a value to it using an assignment operator, it reserves a separate memory space in the process stack which would be identified by the identifier you used (blue). Clearly this memory address will not the same as that image[i][j], where the averaging needs to happen, hence the behaviour.

Perhaps you thought that you creating a variable would make it point to the RHS of assignment operator. While this is true in some languages like python and javascript, C does not behave that way.

CodePudding user response:

I thought they will point there , out of pure human logic

Heh well, take that up with the creators of C. float blue = image[i][j].rgbtBlue; et al, creates a copy of the value, two distinct memory spaces. Mutating one doesn't affect the other. C does, however, have pointers, types whose values are memory addresses. You can have several pointers point to the same location in memory, and you can dereference any of them to read/write the memory they point to. For example, you can do the following:

...
// in this context, the * means declare blue as a float _pointer_. That is, a
// pointer that points to a float value.  The & means "take the address of",
// in this case, the address of image[i][j].rgbBlue. I don't _think_ the
// parenthesis are necessary, but I routinely forget the order of operations
// in C, so I prefer using them when there's any doubt.
float* blue = &(image[i][j].rgbtBlue);

// and declare pointers for green and red as well
float* green = &(image[i][j].rgbtGreen);
float* red = &(image[i][j].rgbtRed);

// In this context, the * means _dereference_ the pointer. That is, retrieve the
// value the pointer points to, which is the float image data
int average_color = round((*blue   *green   *red) /3);
//image[i][j].rgbtBlue = image[i][j].rgbtGreen = image[i][j].rgbtRed = average_color;
// again, we want to dereference with *. This will assign average_color to each
// of the memory spaces that red, blue, and green point to
*red = *blue = *green = average_color;

// now, image[i][j].rgbtBlue, et al, will hold the value of average_color

One more thing, round returns a double, your compiler should be warning that you're assigning this to an int. Use roundf (described in same link above) instead and make that float average_color.

  •  Tags:  
  • c
  • Related