Hi,
I just need to know using aspose library can we compress PPT without distorting quality? I have attached one PPT in the below link which around 38 Mb, can it be compressed to 5 Mb using Also we need PDF compressing as well. We need to compress PDF and Compress PPT from 50 mb to 5 mb without any quality change using Aspose and dotnet core? If possible then we are going to purchase this library.
Below is the PPT link. please compress it.
@PitabasPradhan,
Thank you for the inquiry.
It will take me a while for some research. We will reply to you as soon as possible.
@PitabasPradhan,
The presentation size is 38MB because the slide with number 32 contains a large PNG image (8272 x 6200, ~36 MB) but the display area is small (360 x 350). In such cases, images can be reduced to the size of the displayed area without loss of quality. This can greatly reduce the presentation file size. The following code example performs this operation for the slide with number 32 by using Aspose.Slides.
using (var presentation = new Presentation("YaleCordageReport.ppt"))
{
var slide = presentation.Slides[31];
foreach (var shape in slide.Shapes)
{
if (shape is PictureFrame pictureFrame)
{
ResizeImage(pictureFrame);
}
}
presentation.Save("slide_32_images_are_resized.pptx", SaveFormat.Pptx);
}
static void ResizeImage(IPictureFrame frame)
{
Debug.Assert(frame != null);
var scaledSize = FitImageSize(frame);
if (scaledSize == null)
{
// do nothing
return;
}
var contentType = frame.PictureFormat.Picture.Image.ContentType;
if (contentType == "image/png")
{
using (var bitmap = new Bitmap(frame.PictureFormat.Picture.Image.SystemImage))
{
var rounding = MidpointRounding.AwayFromZero;
var newWidth = (int)Math.Round(scaledSize.Value.Width, rounding);
var newHeight = (int)Math.Round(scaledSize.Value.Height, rounding);
var newBitmap = ResizeImage(bitmap, newWidth, newHeight);
var imageStream = new MemoryStream();
newBitmap.Save(imageStream, ImageFormat.Png);
imageStream.Seek(0, SeekOrigin.Begin);
var newData = new byte[imageStream.Length];
imageStream.Read(newData, 0, newData.Length);
frame.PictureFormat.Picture.Image.ReplaceImage(newData);
}
}
else if (contentType == "image/jpg")
{
// todo: compress JPG image in the same way
}
}
static SizeF? FitImageSize(IPictureFrame frame)
{
Debug.Assert(frame != null);
var imageWidth = frame.PictureFormat.Picture.Image.Width;
var imageHeight = frame.PictureFormat.Picture.Image.Height;
if (frame.Width > imageWidth && frame.Height > imageHeight)
{
return null;
}
var widthRatio = imageWidth / frame.Width;
var heightRatio = imageHeight / frame.Height;
var scaledWidth = 0f;
var scaledHeight = 0f;
if (widthRatio > heightRatio)
{
scaledWidth = frame.Width;
scaledHeight = imageHeight / widthRatio;
}
else
{
scaledHeight = frame.Height;
scaledWidth = imageWidth / heightRatio;
}
return new SizeF(scaledWidth, scaledHeight);
}
static Bitmap ResizeImage(Image image, int newWidth, int newHeight)
{
Debug.Assert(image != null);
Debug.Assert(newWidth > 0);
Debug.Assert(newHeight > 0);
var destRect = new Rectangle(0, 0, newWidth, newHeight);
var destImage = new Bitmap(newWidth, newHeight);
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;
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
}
return destImage;
}
The size of the output presentation file is 3.9MB without loss of quality slide_32_images_are_resized.zip (3.7 MB)
Note: this code example is appropriate for the provided presentation and does not take into account other options that may apply to images (rotation, for example) in other presentations and can be improved.
But I have found some problems when doing the same operation for all slides. So I’ve added a ticket with ID SLIDESNET-43023 in our issue tracking system. Our development team will investigate this case. You will be notified when the issue is resolved. Then you can be able to achieve your purposes with Aspose.Slides.
@PitabasPradhan,
Our developers have found a flaw in my code example above. It should be taken into account that the same image with different sizes can be used in different places in the presentation. The following code example reduces all PNG images in the presentation without quality loss:
using (var presentation = new Presentation("YaleCordageReport.ppt"))
{
Dictionary<IPPImage, SizeF> imagesToNewSize = new Dictionary<IPPImage, SizeF>();
foreach (var slide in presentation.Slides)
{
foreach (var shape in slide.Shapes)
{
if (shape is PictureFrame pictureFrame)
{
IPPImage ppImage = pictureFrame.PictureFormat.Picture.Image;
SizeF? pictureFrameSize = FitImageSize(pictureFrame);
if (imagesToNewSize.ContainsKey(ppImage))
{
if (pictureFrameSize.HasValue && pictureFrameSize.Value.Width > imagesToNewSize[ppImage].Width)
{
imagesToNewSize[ppImage] = pictureFrameSize.Value;
}
}
else if (pictureFrameSize.HasValue)
{
imagesToNewSize.Add(ppImage, pictureFrameSize.Value);
}
}
}
}
foreach (var imageToSize in imagesToNewSize)
{
ResizeImage(imageToSize.Key, imageToSize.Value);
}
presentation.Save("slide_All_images_are_resized.pptx", SaveFormat.Pptx);
}
static void ResizeImage(IPPImage ppImage, SizeF scaledSize)
{
var contentType = ppImage.ContentType;
if (contentType == "image/png")
{
using (var bitmap = new Bitmap(ppImage.SystemImage))
{
var rounding = MidpointRounding.AwayFromZero;
var newWidth = (int)Math.Round(scaledSize.Width, rounding);
var newHeight = (int)Math.Round(scaledSize.Height, rounding);
var newBitmap = ResizeImage(bitmap, newWidth, newHeight);
var imageStream = new MemoryStream();
newBitmap.Save(imageStream, ImageFormat.Png);
imageStream.Seek(0, SeekOrigin.Begin);
var newData = new byte[imageStream.Length];
imageStream.Read(newData, 0, newData.Length);
ppImage.ReplaceImage(newData);
}
}
else if (contentType == "image/jpg")
{
// todo: compress JPG image in the same way
}
}
static Bitmap ResizeImage(Image image, int newWidth, int newHeight)
{
Debug.Assert(image != null);
Debug.Assert(newWidth > 0);
Debug.Assert(newHeight > 0);
var destRect = new Rectangle(0, 0, newWidth, newHeight);
var destImage = new Bitmap(newWidth, newHeight);
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;
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
}
return destImage;
}
static SizeF? FitImageSize(IPictureFrame frame)
{
Debug.Assert(frame != null);
var imageWidth = frame.PictureFormat.Picture.Image.Width;
var imageHeight = frame.PictureFormat.Picture.Image.Height;
if (frame.Width > imageWidth && frame.Height > imageHeight)
{
return null;
}
var widthRatio = imageWidth / frame.Width;
var heightRatio = imageHeight / frame.Height;
var scaledWidth = 0f;
var scaledHeight = 0f;
if (widthRatio > heightRatio)
{
scaledWidth = frame.Width;
scaledHeight = imageHeight / widthRatio;
}
else
{
scaledHeight = frame.Height;
scaledWidth = imageWidth / heightRatio;
}
return new SizeF(scaledWidth, scaledHeight);
}
The issues you have found earlier (filed as SLIDESNET-43023) have been fixed in Aspose.Slides for .NET 22.5 (ZIP, MSI).
You can check all fixes on the Release Notes page.
You can also find the latest version of our library on the Product Download page.