private static bool ResampleCore(ImageData imageData, SizeF shapeSizeInPoints, int ppi, int jpegQuality)
{
// The are actually several shape types that can have an image (picture, ole object, ole control), let's skip other shapes.
if (imageData == null)
return false;
// An image can be stored in the shape or linked from somewhere else. Let's skip images that do not store bytes in the shape.
byte[] originalBytes = imageData.ImageBytes;
if (originalBytes == null)
return false;
// Ignore metafiles, they are vector drawings and we don't want to resample them.
ImageType imageType = imageData.ImageType;
if (imageType.Equals(ImageType.Wmf) || imageType.Equals(ImageType.Emf))
return false;
try
{
double shapeWidthInches = ConvertUtil.PointToInch(shapeSizeInPoints.Width);
double shapeHeightInches = ConvertUtil.PointToInch(shapeSizeInPoints.Height);
// Calculate the current PPI of the image.
ImageSize imageSize = imageData.ImageSize;
double currentPpiX = imageSize.WidthPixels / shapeWidthInches;
double currentPpiY = imageSize.HeightPixels / shapeHeightInches;
Console.Write("Image PpiX:{0}, PpiY:{1}. ", (int)currentPpiX, (int)currentPpiY);
// Let's resample only if the current PPI is higher than the requested PPI (e.g. we have extra data we can get rid of).
if ((currentPpiX <= ppi) || (currentPpiY <= ppi))
{
Console.WriteLine("Skipping.");
return false;
}
using (Image srcImage = imageData.ToImage())
{
// Create a new image of such size that it will hold only the pixels required by the desired ppi.
int dstWidthPixels = (int)(shapeWidthInches * ppi);
int dstHeightPixels = (int)(shapeHeightInches * ppi);
using (Bitmap dstImage = new Bitmap(dstWidthPixels, dstHeightPixels))
{
// Drawing the source image to the new image scales it to the new size.
using (Graphics gr = Graphics.FromImage(dstImage))
{
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.DrawImage(srcImage, 0, 0, dstWidthPixels, dstHeightPixels);
}
// Create JPEG encoder parameters with the quality setting.
ImageCodecInfo encoderInfo = GetEncoderInfo(ImageFormat.Jpeg);
EncoderParameters encoderParams = new EncoderParameters();
encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, jpegQuality);
// Save the image as JPEG to a memory stream.
MemoryStream dstStream = new MemoryStream();
dstImage.Save(dstStream, encoderInfo, encoderParams);
// If the image saved as JPEG is smaller than the original, store it in the shape.
Console.WriteLine("Original size {0}, new size {1}.", originalBytes.Length, dstStream.Length);
if (dstStream.Length < originalBytes.Length)
{
dstStream.Position = 0;
imageData.SetImage(dstStream);
return true;
}
}
}
}
catch (Exception e)
{
// Catch an exception, log an error and continue if cannot process one of the images for whatever reason.
Console.WriteLine("Error processing an image, ignoring. " + e.Message);
}
return false;
}