Search code examples
ctype-conversionvariable-assignmentstb-image

Is there a way to access and change the saturation values of a grayscale bitmap in c?


I haven't programmed in c for about 9 years, and I've never been that good (with any language) either. Now, I'm trying to brute-force my way back in, converting some Matlab code into c, and some stuff is still very rusty.

I'm trying to read an 8bit-bmp into a c file. Then I'd like to change the saturation level (0-255) of each specific bit.

I did find the stb_image library, but I'm not sure what am I actually loading through:

 #include <stdio.h>  
 #include <stdlib.h>  
   
 #define STB_IMAGE_IMPLEMENTATION  
 #define STBI_ONLY_BMP  
 #define STB_IMAGE_WRITE_IMPLEMENTATION  
 #include "stb_image/stb_image.h"  
 #include "stb_image/stb_image_write.h"  
 
 
 int main(void) {    
      int width, height, channels;    
      int i,j;    
      unsigned char *img = stbi_load("filename", &width, &height, &channels, 1);

But if it's an unsigned char, it's a 8bit value. And if it's a 8bit .bmp, and I'm loading 1 channel, it's gotta be the saturation in binary. Which then led me to the question: how can I access inside each byte and change the values? Is it through something like this?

for (i=1;i<=1440;i++){  
    for (j=1;j<=1080;j++){  
        if(*(*(img + i) + j)<100){  
            *(*(img + i) + j) = 0;  
        }  
        else{  
            *(*(img + i) + j) = 255;  
        }  
    }  
 }  

Well, of course it isn't. Silly me.

../srctt/tryout.c:17:28: error: invalid type argument of unary ''(have 'int')
17 | if(
(*(img + i) +j)<100){

So... I have to loop through all of the unsigned char array and convert it 1 by 1 to an int array with the same size? I feel that I'm missing something here. There's either a better library to read images, or some kind of easy conversion that I should be doing.

Then, afterwards, I'd also like to save the array into a bmp (like below), but does that mean I have to run another loop to convert every int into an unsigned char back?

stbi_write_bmp("filename", 1440, 1080, 0, img);  
stbi_image_free(img);

Thanks in advance. I know, reaaaaaaally rusty shenanigans here.


Solution

  • You're not really interested in scanlines, so just do:

    for (k=0; k<width*height; k++)
        img[k] = ...
    

    If you are, then:

    for (y=0; y<height; y++)
        for (x=0; x<width; x++)
            img[y*width+x] = ...