title: How can I compress images in PowerPoint via C#?
body: <p>I am using C# to generate a bunch of SSRS Reports offscreen, and then take the created image(s) for each report and paste them into a PowerPoint presentation, effectively collating all the reports together into one pack.  While this works fine, it results in a filesize of 23mb, for only a 26 page presentation. (I undersand that using a high dpi has partly resulted in this monster number, but has proved necessary to create an image of the required clarity).</p>
  
  <p>When I save this presentation manually within PowerPoint however, the file size reduces to approximately 13mb.  (This is with the compress pictures option Target output set to 96dpi).  Is there a way I can command Powerpoint to save all the images at a lower resolution from within my code so the generated file is smaller?</p>
  
  <p>(Currently, throughout my process, the file is being saved when called by the SlidePart <code>.Save()</code> command only.)</p>
  
  <h2>Further information</h2>
  
  <p>I am generating the images off-screen at 600dpi.  When a lower resolution is used, the image quality drops off when printing and random fuzzy artefacts start appearing between the letters (I assume due to some form of anti-aliasing)</p>
  
  <p>This results in images being created, that when pasted into PowerPoint, are a huge 121cm x 171cm which are scaled at 16%.  However, once I view this presentation in PowerPoint, and subsequently save it, it reduces the image size down to the slide size at 100% scale, with no loss of quality.</p>
  
  <p>I suppose the question is, how can I instruct my program to perform this resizing transformation?  The code I’m using is as follows</p>
  
  <pre><code>private void ReplaceSlideImage(SlidePart slidePart, byte[] imageData, int imageWidth, int imageHeight, ImagePartType imageType)
  {
    // The ratio of the image size to the slide size
    // Set to 1.0 to make the image fill the slide, or &lt; 1.0 to leave a border
    const double IMAGE_SCALE_FACTOR = 1.0;
  
    Slide theSlide = slidePart.Slide;
    double slideAspectRatio = 0.0;
    double imageAspectRatio = 0.0;
  
    System.IO.MemoryStream imageStream = null;
  
    // Look for the first embedded image on the slide.
    Drawing.Blip blip = theSlide.Descendants&lt;Drawing.Blip&gt;().FirstOrDefault();
  
    if (blip != null)
    {
      // Add the new image part.
      ImagePart newImagePart = slidePart.AddImagePart(imageType);
  
      imageStream = new MemoryStream(imageData);
      newImagePart.FeedData(imageStream);
      blip.Embed = slidePart.GetIdOfPart(newImagePart);
  
      // Scale the image to fit the slide
      SlideSize slideSize = m_file.PresentationPart.Presentation.Descendants&lt;SlideSize&gt;().First();
      Transform2D imageTransform = slidePart.Slide.Descendants&lt;Transform2D&gt;().First();
  
      slideAspectRatio = (double)slideSize.Cx / (double)slideSize.Cy;
      imageAspectRatio = (double)imageWidth / (double)imageHeight;
  
      if (imageAspectRatio &gt; slideAspectRatio)
      {
        imageTransform.Extents.Cx = (Int64)(slideSize.Cx * IMAGE_SCALE_FACTOR);
        imageTransform.Extents.Cy = (Int64)(slideSize.Cx * IMAGE_SCALE_FACTOR / imageAspectRatio);
      }
      else
      {
        imageTransform.Extents.Cy = (Int64)(slideSize.Cy * IMAGE_SCALE_FACTOR);
        imageTransform.Extents.Cx = (Int64)(slideSize.Cy * IMAGE_SCALE_FACTOR * imageAspectRatio);
      }
  
      // Recentre the image to the middle of the slide 
      imageTransform.Offset.X = (slideSize.Cx / 2) - (imageTransform.Extents.Cx / 2);
      imageTransform.Offset.Y = (slideSize.Cy / 2) - (imageTransform.Extents.Cy / 2);
  
      theSlide.Save();
  
      // Dispose of the image stream
      imageStream.Dispose();
    }
  }
  </code></pre>