0

How to do this programmatically in C#? I´m using MS Office Professional 2016

enter image description here .

To insert an image I use this code:

        DialogResult result;
        OpenFileDialog ofd = new OpenFileDialog();
        ofd.Title = "Choose image file";
        result = ofd.ShowDialog();

        if (result == DialogResult.OK)
        {
            //GetInstance().ActiveSheet.Shapes.AddPicture(ofd.FileName, MsoTriState.msoFalse, MsoTriState.msoCTrue, 10, 10, -1, -1);
            GetInstance().ActiveSheet.Shapes.AddPicture2(ofd.FileName, MsoTriState.msoFalse, MsoTriState.msoCTrue, 10, 10, -1, -1, 1);
            Excel.Shape newShape = GetInstance().ActiveSheet.Shapes.Item(GetInstance().ActiveSheet.Shapes.Count);
            newShape.ZOrder(MsoZOrderCmd.msoSendToBack);
            newShape.Placement = Excel.XlPlacement.xlMoveAndSize;
        }

Then I have my images as shapes. Maybe there is a way to do the picture compression on shapes?

prototype0815
  • 592
  • 2
  • 7
  • 24

1 Answers1

0

There are several ways to get the job done:

  1. The enter link description here provides the last argument compress which allows specifying whether the picture should be compressed when inserted. You can use the following values:

    • msoPictureCompressDocDefault - The picture is compressed or not depending on the settings for the document.
    • msoPictureCompressFalse - The picture is not compressed.
    • msoPictureCompressTrue - The picture will be compressed.
  2. You can use .net BCL classes to reduce the size of image before adding it to Excel documents:

/// <summary>
/// Resize the image to the specified width and height.
/// </summary>
/// <param name="image">The image to resize.</param>
/// <param name="width">The width to resize to.</param>
/// <param name="height">The height to resize to.</param>
/// <returns>The resized image.</returns>
public static Bitmap ResizeImage(Image image, int width, int height)
{
    var destRect = new Rectangle(0, 0, width, height);
    var destImage = new Bitmap(width, height);

    destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

    using (var graphics = Graphics.FromImage(destImage))
    {
        graphics.CompositingMode = CompositingMode.SourceCopy;
        graphics.CompositingQuality = CompositingQuality.HighQuality;
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphics.SmoothingMode = SmoothingMode.HighQuality;
        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

        using (var wrapMode = new ImageAttributes())
        {
            wrapMode.SetWrapMode(WrapMode.TileFlipXY);
            graphics.DrawImage(image, destRect, 0, 0, image.Width,image.Height, GraphicsUnit.Pixel, wrapMode);
        }
    }

    return destImage;
}

You may find more ways and information:

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • I got following results of the three different ways: not compressed XLSX 615kB, compressed by Shapes.AddPicture2() XLSX 609kB, compressed by hand (like at the screenshot) XLSX 404kB. So, the compression of Shapes.AddPicture2() is not nearly as good as to do it by hand. – prototype0815 May 05 '20 at 08:51
  • Thank you for your ResizeImage() function. But how can I get the resiszed bitmap into the shape? – prototype0815 May 05 '20 at 08:53
  • You need to save the new image to a disk and then pass the file path to the `AddPicture2` method. – Eugene Astafiev May 05 '20 at 17:12
  • I thought so... Not exaclty a great solution. But I'll give it a try. – prototype0815 May 07 '20 at 07:54
  • This method doesn't compress as much as the manual one. Not even if I set the quality from high to low. – prototype0815 May 07 '20 at 11:13