public static void SaveAsTopQualityJpeg(Image image, string destinationPath)
{
var jpgEncoder = ImageCodecInfo.GetImageDecoders().First(codec => codec.FormatID == ImageFormat.Jpeg.Guid);
var encoder = Encoder.Quality;
//nb: there are cases (notably http://jira.palaso.org/issues/browse/WS-34711, after cropping a jpeg) where we get out of memory if we are not operating on a copy
// Use a temporary file pathname in the destination folder. This is needed to ensure proper permissions are granted
// to the resulting file later after FileUtils.ReplaceFileWithUserInteractionIfNeeded is called. That method may call
// File.Replace which replaces both the file content and the file metadata (permissions). The result of that if we use
// the user's temp directory is described in http://issues.bloomlibrary.org/youtrack/issue/BL-3954.
using (var temp = TempFile.InFolderOf(destinationPath))
using (var safetyImage = new Bitmap(image))
{
using(var parameters = new EncoderParameters(1))
{
//0 = max compression, 100 = least
parameters.Param[0] = new EncoderParameter(encoder, 100L);
SIL.IO.RobustIO.SaveImage(safetyImage, temp.Path, jpgEncoder, parameters);
}
SIL.IO.FileUtils.ReplaceFileWithUserInteractionIfNeeded(temp.Path, destinationPath, null);
}
}