Thread: questions about bitmap edit

  1. #1
    Registered User
    Join Date
    Dec 2014
    Posts
    4

    Post questions about bitmap edit

    I would like to write a program that can ask for an x,y coordinates and hence draw circle on a imported bitmap.
    It can draw circles on the imported bitmap and show the image after each edit.
    I have done most part about how to read and allocate memories of bitmap,
    but I got difficulties with how to draw circles and how to save the result image as output.bmp
    I wish I can have help with void SaveFile and void DrawCircle.
    Thank you for any help.

    Code:
    #pragma pack(push, 1)
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    
    
    typedef int32_t int32;
    typedef int16_t int16;
    typedef uint8_t byte;
    
    
    typedef struct {
        byte      signatureB;        
        byte      signatureM;        
        int32     fileSize;            
        int16     reserved1;        
        int16     reserved2;        
        int32     imageOffset;        
    } BMPHeader;
    
    
    typedef struct {
        int32     size;                
        int32     imageWidth;        
        int32     imageHeight;        
        int16     colorPlanes;        
        int16     bitsPerPixel;        
        byte      extra[24];
    } BMPInfoHeader;
    
    
    typedef struct {
        byte blue;
        byte green;
        byte red;
    } Pixel;
    
    
    BMPHeader bmpHeader;                
    BMPInfoHeader bmpInfoHeader;        
    
    
    Pixel* LoadBitmap(char* bmpFilename) {
        FILE *filePtr;                        
        Pixel *bitmapImage = NULL; 
        
        
        filePtr = fopen(bmpFilename, "rb");
        if (filePtr == NULL) {
            printf("Input bitmap not found...it should be in your project directory or same directory as your exe if stand-alone\n");
            return NULL;
        }
    
    
        
        fread(&bmpHeader, sizeof(BMPHeader), 1, filePtr);
    
    
        if (bmpHeader.signatureB != 'B' || bmpHeader.signatureM != 'M') {
            printf("Input file not a BMP... have you saved it properly as a bitmap file?\n");
            fclose(filePtr);
            return NULL;
        }
    
    
        printf("Reported file size: %d\n", bmpHeader.fileSize);
        printf("Offset for image data: %d\n", bmpHeader.imageOffset);
    
    
        
        fread(&bmpInfoHeader, sizeof(BMPInfoHeader), 1, filePtr);
        if (bmpInfoHeader.bitsPerPixel != 24) {
            printf("Input file not 24-bit BMP... Plese save as 24 bit BMP only\n");
            fclose(filePtr);
            return NULL;
        }
        
        printf("Reported image width: %d\n", bmpInfoHeader.imageWidth);
        printf("Reported image height: %d\n", bmpInfoHeader.imageHeight);
        printf("Number of bits per pixel: %d\n", bmpInfoHeader.bitsPerPixel);
    
    
        
        fseek(filePtr, bmpHeader.imageOffset, SEEK_SET);
    
    
        
        int imageSize = bmpInfoHeader.imageWidth*bmpInfoHeader.imageHeight*3; 
        printf("Image size: %d\n", imageSize);
        bitmapImage = (Pixel*)malloc(imageSize);
        
        
        fread(bitmapImage, sizeof(Pixel), bmpInfoHeader.imageWidth*bmpInfoHeader.imageHeight, filePtr);
        
        fclose(filePtr);
        return bitmapImage;
    }
    
    
    void SaveFile(char* filename) {
    }    
    
    void DrawCircle(){
    }
    
    
    void ShowImage(Pixel* image) {
        
    
    
        int i, j;
        
        for (i = bmpInfoHeader.imageHeight-1; i >= 0; i--) {
            for (j = 0; j < bmpInfoHeader.imageWidth; j++) {
                Pixel p = image[i*bmpInfoHeader.imageWidth + j];  
                
                double mono = (0.2125 * p.red + 0.7154 * p.green + 0.0721 * p.blue)/255;    // convert to monochrome
    
    
                if (mono < 0.2) {
                    printf("%c", ' ');
                } else if (mono < 0.4) {
                    printf("%c", 176);
                } else if (mono < 0.6) {
                    printf("%c", 177);
                } else {
                    printf("%c", 178);
                }
                
            }
            printf("\n");
        }
    
    
    }
        
    
    
    int main(void) {
        system("chcp 437");        
        Pixel* image = LoadBitmap("input.bmp");
    
    
        printf("\nTop-Left Pixel -               Blue: %d Green: %d Red: %d\n", image[0].blue, image[0].green, image[0].red); // example
        printf("Pixel next to Top-Left Pixel - Blue: %d Green: %d Red: %d\n\n", image[1].blue, image[1].green, image[1].red); // example
    
    
        printf("Please enter the coordinates of the circle center x,y \n Entering 0 for both x and y to quit and save the output");
        int x, y;
        scanf("%d%d", &x, &y);
        while (x != 0 || y != 0){
            char ch = getchar();
            DrawCircle();
            ShowImage(image);
            printf("Please enter the coordinates of the circle center x,y \n Entering 0 for both x and y to quit and save the output");
            scanf("%d%d", &x, &y);
        }
        SaveFile("output.bmp");
    }
    Last edited by matthewxd; 12-06-2016 at 06:27 PM.

  2. #2
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    To save the bmp just fwrite out the headers and image data. Copy all your freads and turn them into fwrites. That will get you most (all?) the way there. Remember to open for writing in the binary mode (especially important on windows). The fseek shouldn't be necessary as long as the image data offset is 54 (more specifically sizeof(BMPHeader)+sizeof(BMPInfoHeader) with all padding removed). If it isn't 54, I'd just set it to 54 in the header and write it out like that (not bothering to read/save/write whatever stuff you may have skipped over in the input file, if anything).

    As for the circle, there is the midpoint circle algorithm. Look at the C implementation there. Of course, that's just a plain old circle, not an antialiased one.

  3. #3
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    So did you get this to work?

    I forgot to mention that each row of a bmp image is rounded up to a multiple of 4 bytes. So your method of reading in the image data into your Pixel array won't work for an image whose width is not a multiple of 4.

  4. #4
    Registered User
    Join Date
    Dec 2014
    Posts
    4
    Thank you , I can solve the savefile part
    but the part of drawing circle cannot be solved.
    I cant use graphics.h for the program.
    I need to change the pixel color data stored in the malloc array and write it back into the output.bmp
    but I dont know how to do this

  5. #5
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    So you fixed the rows-are-a-multiple-of-4-bytes issue? In the code you posted you are doing it incorrectly. To check, make a bmp file with a width of 15 (i.e., a width that is not divisible by 4) and look at your textual display. Make the image a cross or something simple like that.

    As for the circle, did you look at the C code in the link I gave? What is your trouble in implementing (copying) it? Changing the pixel color is easy. Just set each calculated pixel position of the circle to
    Code:
    (Pixel){0, 0, 0}
    or whatever (0,0,0 would be black).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 0
    Last Post: 03-16-2012, 09:59 AM
  2. Bitmap Rotation System Questions
    By loopshot in forum Game Programming
    Replies: 2
    Last Post: 05-13-2005, 01:32 PM
  3. Edit Control Questions
    By Jaken Veina in forum Windows Programming
    Replies: 2
    Last Post: 04-18-2005, 05:34 PM
  4. Edit Box Questions PT. II
    By Quantrizi in forum Windows Programming
    Replies: 16
    Last Post: 08-12-2003, 10:42 PM
  5. Lots Of Bitmap Texture Questions:
    By Krak in forum Game Programming
    Replies: 7
    Last Post: 07-10-2003, 08:16 PM

Tags for this Thread