title: How to shrink an image size?
body: <p>Hello I am working on a program to shrink a 640x480 bit map image into a 320x240 image. I have been researching the issue for a while now but all the good examples i have found have been for increasing the size of an image.</p>
  
  <p>(See here:<a href="http://cboard.cprogramming.com/c-programming/154737-help-program-resize-image.html" rel="nofollow">http://cboard.cprogramming.com/c-programming/154737-help-program-resize-image.html</a>)</p>
  
  <p>I am having difficulty translating what was done in that program to what needs to be done in mine. 
  Here is my code sofar:</p>
  
  <pre><code>include stdio.h
  include stdlib.h
  include string.h
  include math.h
  
  
  pragma pack(push, 1)
  typedef struct tagBITMAPFILEHEADER
  {
  unsigned short bfType; //specifies the file type
  unsigned int bfSize; //specifies the size in bytes of  the bitmap file
  unsigned short bfReserved1; //reserved; must be 0
  unsigned short bfReserved2; //reserved; must be 0
  unsigned int bfOffBits; //species the offset in bytes from the bitmapfileheader to the bitmap bits
  } BITMAPFILEHEADER;
  pragma pack(pop)
  
  pragma pack(push, 1)
  typedef struct tagBITMAPDIBHEADER
  {
  unsigned int biSize; //specifies the number of bytes required by the struct
  int biWidth; //specifies width in pixels
  int biHeight; //species height in pixels
  unsigned short biPlanes; //specifies the number of color planes, must be 1
  unsigned short biBitCount; //specifies the number of bit per pixel
  unsigned int biCompression;//spcifies the type of compression
  unsigned int biSizeImage; //size of image in bytes
  int biXPelsPerMeter; //number of pixels per meter in x axis
  int biYPelsPerMeter; //number of pixels per meter in y axis
  unsigned int biClrUsed; //number of colors used by th ebitmap
  unsigned int biClrImportant; //number of colors that are important
  } BITMAPDIBHEADER;
  pragma pack(pop)
  
  pragma pack(push, 1)
  typedef struct
  {
  int  rgbtBlue;
  int  rgbtGreen;
  int  rgbtRed;
  }
  RGBTRIPLE;
  pragma pack(pop)
  
  int main()
  {
  FILE *input, *output;
  BITMAPDIBHEADER inputdibHeader;
  BITMAPFILEHEADER inputfileHeader;
  BITMAPDIBHEADER outputdibHeader;
  BITMAPFILEHEADER outputfileHeader;
  
  int greenValue = 0;
  int blueValue = 0;
  int redValue = 0;
  fopen_s(&amp;output, "test.bmp", "wb");
  if (output == NULL){
      return NULL;
  }
  fopen_s(&amp;input, "lolcat.bmp", "rb");
  if (input == NULL)
      return NULL;
  
  rewind(input);  // rewind the file before reading it again
  fread(&amp;(inputfileHeader), sizeof(BITMAPFILEHEADER), 1, input);
  fread(&amp;(inputdibHeader), sizeof(BITMAPDIBHEADER), 1, input);
  rewind(input);  // rewind the file before reading it again
  fread(&amp;(outputfileHeader), sizeof(BITMAPFILEHEADER), 1, input);
  fread(&amp;(outputdibHeader), sizeof(BITMAPDIBHEADER), 1, input);
  
  
  
  
  
  outputdibHeader.biWidth = inputdibHeader.biWidth *.5;
  outputdibHeader.biHeight = inputdibHeader.biHeight *.5;
  outputfileHeader.bfSize = outputdibHeader.biWidth * outputdibHeader.biHeight;
  outputdibHeader.biSizeImage = inputdibHeader.biSizeImage *.5;
  fwrite(&amp;(outputfileHeader), sizeof(BITMAPFILEHEADER), 1, output);
  fwrite(&amp;(outputdibHeader), sizeof(BITMAPDIBHEADER), 1, output);
  
  rewind(input);
  fseek(input, inputfileHeader.bfOffBits, SEEK_SET);
  fseek(output, outputfileHeader.bfOffBits, SEEK_SET);
  int oldheight = inputdibHeader.biHeight;
  int oldwidth = inputdibHeader.biWidth;
  int i;
  int timeswriten = 0;
  int oldPad = (4 - ((inputdibHeader.biWidth * sizeof(RGBTRIPLE)) % 4)) % 4;
  int newPad = (4 - ((outputdibHeader.biWidth * sizeof(RGBTRIPLE)) % 4)) % 4;
  
  // iterate over infile's scanlines
  for (int i = 0; i &lt; abs(oldheight); i++)
  {
      if (i % 2){
  
  
          // iterate over pixels in scanline
          for (int j = 0; j &lt; oldwidth; j++)
          {
              // temporary storage
              RGBTRIPLE triple;
              fread(&amp;triple, sizeof(RGBTRIPLE), 1, input);
              if (j % 2){
                  fwrite(&amp;triple, sizeof(RGBTRIPLE), 1, output);
              }
              // skip over any input padding
              fseek(input, oldPad, SEEK_CUR);
  
  
          }
      }
      }
  
      fclose(input);
      fclose(output);
  
  } 
  </code></pre>
  
  <p>Currently this code produces a valid bitmap image, however the image created is a very distorted version of the original. Im fairly sure this is due to the way that i am omitting pixels from my new image but I am not sure on what a proper approach for this should be.
  Over all my question is can anyone help explain to me where and how I should be omitting pixels?</p>
  
  <p><strong>Update</strong></p>
  
  <p>I now know that what I am aiming to do is to average 2x2 pixels into one pixels but I can not find a good example on how to do this. Can any please explain this process?</p>
  
  <p><strong>Update 2</strong>
  Thanks to PeterT I know have the following code that appears to be correct by my output is not.</p>
  
  <pre><code> RGBTRIPLE *line_a = (RGBTRIPLE*)malloc(inputdibHeader.biWidth * sizeof(RGBTRIPLE)); /* check malloc() */
  RGBTRIPLE *line_b = (RGBTRIPLE*)malloc(inputdibHeader.biWidth *sizeof(RGBTRIPLE)); /* check malloc() */
  RGBTRIPLE *dest_line = (RGBTRIPLE*)malloc(outputdibHeader.biWidth * sizeof(RGBTRIPLE));
  
      /* move through the target array line by line, consuming two lines from the source
      image at a time */
      /* also assuming you verified the source image is exactly 2x the size of the dest
      malloc() */
  for (i = 0; i &lt; outputdibHeader.biHeight; ++i)
  {
      fread(&amp;(line_a), sizeof(RGBTRIPLE), inputdibHeader.biWidth, input);  /* read scanline &amp; advance file pointer, err check in func */
      fread(&amp;(line_b), sizeof(RGBTRIPLE), inputdibHeader.biWidth, input);/* read scanline &amp; advance file pointer, err check in func */
      for (j = 0; j &lt; outputdibHeader.biWidth; ++j)
      {
          bilinear_filter(&amp;(dest_line[j]), &amp;(line_a[j * 2]), &amp;(line_a[(j * 2) + 1]), &amp;(line_b[j * 2]), &amp;(line_b[(j * 2) + 1]));
      }
      fwrite(&amp;(dest_line), sizeof(RGBTRIPLE), outputdibHeader.biWidth, output);
      /* or something... point is we're creeping through the files scaline by scanline,
      and letting another function handle it to keep this code more intelligble */
  }
  
  fclose(input);
  fclose(output);
  
  }
  void bilinear_filter(RGBTRIPLE *dest, RGBTRIPLE *A, RGBTRIPLE *B, RGBTRIPLE *C, RGBTRIPLE *D)
  {
  
  /* assuming 0888 ARGB */
  dest-&gt;Red = (A-&gt;Red + B-&gt;Red + C-&gt;Red + D-&gt;Red) / 4;
  dest-&gt;Green = (A-&gt;Green + B-&gt;Green + C-&gt;Green + D-&gt;Green) / 4;
  dest-&gt;Blue = (A-&gt;Blue + B-&gt;Blue + C-&gt;Blue + D-&gt;Blue) / 4;
  
  }
  </code></pre>
  
  <p>I think this issue may lie in my header creation so here is that</p>
  
  <pre><code>fread(&amp;(inputHeader), sizeof(TwoHeader), 1, input);
  inputfileHeader = inputHeader.fileHeader;
  inputdibHeader = inputHeader.dibHeader;
  rewind(input);  // rewind the file before reading it again
  fread(&amp;(outputHeader), sizeof(TwoHeader), 1, input);
  outputfileHeader = outputHeader.fileHeader;
  outputdibHeader = outputHeader.dibHeader;
  
  
  outputdibHeader.biWidth = inputdibHeader.biWidth *.5;
  outputdibHeader.biHeight = inputdibHeader.biHeight *.5;
  //outputfileHeader.bfSize = inputfileHeader.bfSize - (inputdibHeader.biWidth*inputdibHeader.biHeight) + outputdibHeader.biWidth*outputdibHeader.biHeight;
  outputfileHeader.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPDIBHEADER)+outputdibHeader.biSizeImage;
  //outputdibHeader.biSizeImage = inputdibHeader.biSizeImage * .25;
  //outputdibHeader.biXPelsPerMeter = inputdibHeader.biXPelsPerMeter * .5;
  //outputdibHeader.biYPelsPerMeter = inputdibHeader.biYPelsPerMeter * .5;
  //fwrite(&amp;(outputfileHeader), sizeof(BITMAPFILEHEADER), 1, output);
  //fwrite(&amp;(outputdibHeader), sizeof(BITMAPDIBHEADER), 1, output);
  fwrite(&amp;(outputHeader), sizeof(TwoHeader), 1, output);
  rewind(input);
  fseek(input, inputfileHeader.bfOffBits, SEEK_SET);
  fseek(output, outputfileHeader.bfOffBits, SEEK_SET);
  </code></pre>
  
  <p>Pardon all the comments its mostly old code or code that I am unsure of.</p>