Advertisement
Guest User

Sprawdź to!

a guest
Jan 19th, 2018
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.80 KB | None | 0 0
  1. #include <iostream>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5.  
  6. #pragma pack(2)
  7. typedef struct tagBITMAPFILEHEADER
  8. {
  9.     unsigned short    bfType;        // must be 'BM'
  10.     unsigned int   bfSize;        // size of the whole .bmp file
  11.     unsigned short    bfReserved1;   // must be 0
  12.     unsigned short    bfReserved2;   // must be 0
  13.     unsigned int   bfOffBits;
  14. } BITMAPFILEHEADER;
  15. #pragma pack()
  16.  
  17. #pragma pack(2)
  18. typedef struct tagBITMAPINFOHEADER
  19. {
  20.     unsigned int  biSize;            // size of the structure
  21.     int   biWidth;           // image width
  22.     int   biHeight;          // image height
  23.     unsigned short   biPlanes;          // bitplanes
  24.     unsigned short   biBitCount;        // resolution
  25.     unsigned int  biCompression;     // compression
  26.     unsigned int  biSizeImage;       // size of the image
  27.     int   biXPelsPerMeter;   // pixels per meter X
  28.     int   biYPelsPerMeter;   // pixels per meter Y
  29.     unsigned int  biClrUsed;         // colors used
  30.     unsigned int  biClrImportant;    // important colors
  31. } BITMAPINFOHEADER;
  32.  
  33. #pragma pack()
  34.  
  35. typedef struct tagRGBTriplet
  36. {
  37.     unsigned char red;
  38.     unsigned char green;
  39.     unsigned char blue;
  40. } RGBTriplet;
  41.  
  42. unsigned char* readBMP(char* filename)
  43. {
  44.     int i;
  45.     FILE* f = fopen(filename, "rb");
  46.     unsigned char info[54];
  47.     fread(info, sizeof(unsigned char), 54, f); // read the 54-byte header
  48.  
  49.     // extract image height and width from header
  50.     int width = *(int*)&info[18];
  51.     int height = *(int*)&info[22];
  52.  
  53.     int size = 3 * width * height;
  54.     unsigned char* data = new unsigned char[size]; // allocate 3 bytes per pixel
  55.     fread(data, sizeof(unsigned char), size, f); // read the rest of the data at once
  56.     fclose(f);
  57.  
  58.     for(i = 0; i < size; i += 3)
  59.     {
  60.         unsigned char tmp = data[i];
  61.         data[i] = data[i+2];
  62.         data[i+2] = tmp;
  63.     }
  64.  
  65.     return data;
  66. }
  67.  
  68. //Now data should contain the (R, G, B) values of the pixels. The color of pixel (i, j) is stored at data[j * width + i], data[j * width + i + 1] and data[j * width + i + 2].
  69. //In the last part, the swap between every first and third pixel is done because windows stores the color values as (B, G, R) triples, not (R, G, B).
  70.  
  71. void writeBMP(char* filename)
  72. {
  73.     BITMAPFILEHEADER bfh;
  74.     BITMAPINFOHEADER bih;
  75.  
  76. /* Magic number for file. It does not fit in the header structure due to alignment requirements, so put it outside */
  77.     unsigned short bfType=0x4d42;
  78.     bfh.bfReserved1 = 0;
  79.     bfh.bfReserved2 = 0;
  80.     bfh.bfSize = 2+sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+640*480*3;
  81.     bfh.bfOffBits = 0x36;
  82.  
  83.     bih.biSize = sizeof(BITMAPINFOHEADER);
  84.     bih.biWidth = 640;
  85.     bih.biHeight = 480;
  86.     bih.biPlanes = 1;
  87.     bih.biBitCount = 24;
  88.     bih.biCompression = 0;
  89.     bih.biSizeImage = 0;
  90.     bih.biXPelsPerMeter = 5000;
  91.     bih.biYPelsPerMeter = 5000;
  92.     bih.biClrUsed = 0;
  93.     bih.biClrImportant = 0;
  94.  
  95.     FILE *file = fopen(filename, "wb");
  96.     if (!file)
  97.     {
  98.         printf("Could not write file\n");
  99.         return;
  100.     }
  101.  
  102. /*Write headers*/
  103.     fwrite(&bfType,1,sizeof(bfType),file);
  104.     fwrite(&bfh, 1, sizeof(bfh), file);
  105.     fwrite(&bih, 1, sizeof(bih), file);
  106.  
  107. /*Write bitmap*/
  108.     for (int y = bih.biHeight-1; y>=0; y--) /*Scanline loop backwards*/
  109.     {
  110.         for (int x = 0; x < bih.biWidth; x++) /*Column loop forwards*/
  111.         {
  112.             /*compute some pixel values*/
  113.             unsigned char r = 255*((float)x/bih.biWidth);
  114.             unsigned char g = 255*((float)y/bih.biHeight);
  115.             unsigned char b = 0;
  116.             fwrite(&b, 1, 1, file);
  117.             fwrite(&g, 1, 1, file);
  118.             fwrite(&r, 1, 1, file);
  119.         }
  120.     }
  121.     fclose(file);
  122. }
  123.  
  124. unsigned char* ConvertBMPToRGBBuffer ( unsigned char* Buffer, int width, int height )
  125. {
  126.     if ((NULL == Buffer) || (width == 0) || (height == 0))
  127.         return NULL;
  128.  
  129.     int padding = 0;
  130.     int scanlinebytes = width * 3;
  131.     while ( ( scanlinebytes + padding ) % 4 != 0 )
  132.         padding++;
  133.  
  134.     int psw = scanlinebytes + padding;
  135.  
  136.     unsigned char* newbuf= new unsigned char[width*height*3];
  137.  
  138.     long bufpos = 0;
  139.     long newpos = 0;
  140.     for ( int y = 0; y < height; y++ )
  141.         for ( int x = 0; x < 3 * width; x+=3 )
  142.         {
  143.             newpos = y * 3 * width + x;
  144.             bufpos = ( height - y - 1 ) * psw + x;
  145.  
  146.             newbuf[newpos] = Buffer[bufpos + 2];
  147.             newbuf[newpos + 1] = Buffer[bufpos+1];
  148.             newbuf[newpos + 2] = Buffer[bufpos];
  149.         }
  150.  
  151.     return newbuf;
  152. }
  153.  
  154. unsigned char* ConvertRGBToBMPBuffer ( unsigned char* Buffer, int width, int height, long* newsize )
  155. {
  156.     if ( ( NULL == Buffer ) || ( width == 0 ) || ( height == 0 ) )
  157.         return NULL;
  158.  
  159.     int padding = 0;
  160.     int scanlinebytes = width * 3;
  161.     while ( ( scanlinebytes + padding ) % 4 != 0 )
  162.         padding++;
  163.  
  164.     int psw = scanlinebytes + padding;
  165.     *newsize = height * psw;
  166.     unsigned char* newbuf = new unsigned char[*newsize];
  167.  
  168.     memset ( newbuf, 0, *newsize );
  169.  
  170.     long bufpos = 0;
  171.     long newpos = 0;
  172.     for ( int y = 0; y < height; y++ )
  173.         for ( int x = 0; x < 3 * width; x+=3 )
  174.         {
  175.             bufpos = y * 3 * width + x;     // position in original buffer
  176.             newpos = ( height - y - 1 ) * psw + x; // position in padded buffer
  177.             newbuf[newpos] = Buffer[bufpos+2];       // swap r and b
  178.             newbuf[newpos + 1] = Buffer[bufpos + 1]; // g stays
  179.             newbuf[newpos + 2] = Buffer[bufpos];     // swap b and r
  180.         }
  181.     return newbuf;
  182.  
  183. }
  184.  
  185. unsigned char* LoadBMP(int* width, int* height, long* size, char* filename)
  186. {
  187.     BITMAPFILEHEADER bmpheader;
  188.     BITMAPINFOHEADER bmpinfo;
  189.     unsigned long bytesread;
  190.  
  191.     FILE *bitmap = fopen(filename, "rb");
  192.     if (NULL == bitmap)
  193.         return NULL;
  194.  
  195.     fread(&bmpheader, 1, sizeof(BITMAPFILEHEADER), bitmap);
  196.  
  197.     fread(&bmpinfo, 1, sizeof(BITMAPINFOHEADER), bitmap);
  198.  
  199.     if(bmpheader.bfType != 0x4d42 )
  200.     {
  201.         fclose(bitmap);
  202.     }
  203.  
  204.     if(&bmpinfo.biCompression!= 0x0000)
  205.     {
  206.         fclose(bitmap);
  207.     }
  208.  
  209.     if(bmpinfo.biBitCount!= 24)
  210.     {
  211.         fclose(bitmap);
  212.     }
  213.  
  214.     *width = bmpinfo.biWidth;
  215.     *height = abs(bmpinfo.biHeight);
  216.     *size = bmpheader.bfSize - bmpheader.bfOffBits;
  217.  
  218.     unsigned char* Buffer = new unsigned char[*size];
  219.  
  220.     fseek(bitmap, bmpheader.bfOffBits ,SEEK_SET);
  221.  
  222.     fread(Buffer, *size, 4, bitmap);
  223.  
  224.     fclose(bitmap);
  225.     return Buffer;
  226. }
  227.  
  228. bool SaveBMP (unsigned char* Buffer, int width, int height, long paddedsize, char* bmpfile)
  229. {
  230.     BITMAPFILEHEADER bmfh;
  231.     BITMAPINFOHEADER info;
  232.     memset ( &bmfh, 0, sizeof (BITMAPFILEHEADER ) );
  233.     memset ( &info, 0, sizeof (BITMAPINFOHEADER ) );
  234.  
  235.     bmfh.bfType = 0x4d42;       // 0x4d42 = 'BM'
  236.     bmfh.bfReserved1 = 0;
  237.     bmfh.bfReserved2 = 0;
  238.     bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + paddedsize;
  239.     bmfh.bfOffBits = 0x36;
  240.  
  241.     info.biSize = sizeof(BITMAPINFOHEADER);
  242.     info.biWidth = width;
  243.     info.biHeight = height;
  244.     info.biPlanes = 1;
  245.     info.biBitCount = 24;
  246.     info.biCompression = 0x0000;
  247.     info.biSizeImage = 0;
  248.     info.biXPelsPerMeter = 0x0ec4;
  249.     info.biYPelsPerMeter = 0x0ec4;
  250.     info.biClrUsed = 0;
  251.     info.biClrImportant = 0;
  252.  
  253.     FILE *bitmap = fopen(bmpfile, "rb");
  254.     if (NULL == bitmap)
  255.         return NULL;
  256.  
  257.     unsigned long bwritten;
  258.  
  259.     fwrite(&bmfh, 1, sizeof(BITMAPFILEHEADER), bitmap);
  260.  
  261.     fwrite(&info, 1, sizeof(BITMAPINFOHEADER), bitmap);
  262.  
  263.     fwrite(Buffer, 1, paddedsize, bitmap);
  264.  
  265.     fclose(bitmap);
  266.     return true;
  267.  
  268. }
  269.  
  270.  
  271. int main()
  272. {
  273.     int x, y;
  274.     long s;
  275.     unsigned char* b = LoadBMP ( &x, &y, &s, "testbitmap.bmp" );
  276.     SaveBMP ( b, x, y, s, "nowabitmapa.bmp" );
  277.     delete [] b;
  278.  
  279. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement