-1

If in the below snippet of code (at the bottom of this post) I need to write a function that will turn a BMP into grayscale, how would I go about? Note that the main of the program is already written, and has all the open/close file features etc. written - this just needs the function itself.

My assignment requires that for each pixel the values of red, green, and blue are converted into an average value of the three so as to become somewhat grayscale, but am at a loss of how to even begin.

The following libraries are included - again, note that this is in a separate file:

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

Here's the snippet of code I have to fill out:

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

I have played around with the below potential solution, but my use of image[height][width] doesn't seem to work. And then of course I need to replace the 0x00 with a calculation that provides the average of the three. But not quite sure how to go about improving this.


{

    if(( image[height][width].rgbtRed==0xff && image[height][width].rgbtBlue==0x00 && image[height][width].rgbtGreen==0x00)||(image[height][width].rgbtRed==0xff && image[height][width].rgbtBlue==0xff && image[height][width].rgbtGreen==0xff)) 
    {
        image[height][width].rgbtRed=0x00;
        image[height][width].rgbtBlue=0x00;
        image[height][width].rgbtGreen=0x00;
    }
    return;
}

(I apologize if my lingo is mistaken - I'm a very novice learner.)

Simson
  • 3,373
  • 2
  • 24
  • 38
thestacker
  • 81
  • 8
  • 1
    There's no code here for decoding or encoding BMPs. Are you using a library? And "average of the three" is a terrible way to convert RGB to gray. Far better is 0.299R + 0.587G + 0.114B. – Lee Daniel Crocker Oct 04 '19 at 00:31
  • There's no code - correct. Asking for help to fill that out. Again, the main features are in other files. This is exclusively for running through the image, and then converting it pixel by pixel. The "average of the three" is the instruction I've been given for my task so that's what I have to play with. – thestacker Oct 04 '19 at 00:34
  • 2
    What part are you having trouble with? We aren't going to write your code for you, so let us know what specifically you don't get so we can answer your question. – user1118321 Oct 04 '19 at 01:02
  • Added an update... – thestacker Oct 04 '19 at 01:18

2 Answers2

1

What you need to do is to calculate the colour for every pixel, either using a naive average, the formula 0.299R + 0.587G + 0.114B suggested by @Lee Daniel Crocker in comments or some other method then set the value of R G and B pixels all to the same value and the picture is grey.

Something like this

void grayscale(int height, int width, RGBTRIPLE image[][]){
    for(int x=0; x<width ; x++){
        for(int y=0; y<height; y++){
            unsigned int colour = 0.299*image[x][y].rgbtRed + 0.587*image[x][y].rgbtGreen + 0.114*image[x][y].rgbtBlue;
            image[x][y].rgbtRed = colour & 0xFF;
            image[x][y].rgbtBlue = colour & 0xFF;
            image[x][y].rgbtGreen = colour & 0xFF;
         }
    }
}

Check your if your data types are unsigned so you are not surprised by signed bytes messing up additions for values over 127

Simson
  • 3,373
  • 2
  • 24
  • 38
  • It sounds serious. Is there no error message about what and where? – Simson Oct 04 '19 at 02:42
  • https://cs50.stackexchange.com/a/31366 One of the explanations is signed integer overflow. I know `colour` cannot be over 255 but maybe this is not clear in the code. I will update – Simson Oct 04 '19 at 03:43
  • Is the image at least only grey colours? Then modify with the floating point multiplications, as suggested in comments and post. – Simson Oct 04 '19 at 12:48
  • then load the code in your debugger and single step to verify the code is executed in the way it is intended. – Simson Oct 04 '19 at 12:54
  • Height and width could be mixed up. – Simson Oct 04 '19 at 12:57
  • What does `& 0xFF` part do? – Hrvoje T Jul 10 '20 at 11:37
  • It masks the lowest 8 bits of the variable before the assignment to an 8 bit variable. A pedantic compiler could warn even though we know `colour` cannot be bigger than any of the rgbt variables. in size – Simson Jul 11 '20 at 11:32
0
for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width; j++)
    {
        int gray = 
             (image[i][j].rgbtRed + image[i][j].rgbtGreen + image[i][j].rgbtBlue) / 3.0 ;
        image[i][j].rgbtRed = gray ;
        image[i][j].rgbtGreen = gray;
        image[i][j].rgbtBlue = gray;
    }
}

return;
David Buck
  • 3,752
  • 35
  • 31
  • 35
  • 1
    thanks for taking the time to write an answer, it would be great if you could provide an explanation on where the author of this question had missed or how they could reach to your solution. – Van_Cleff Jun 17 '20 at 19:39