mirror of
https://github.com/greenshot/greenshot
synced 2025-08-14 10:47:02 -07:00
Due to a GDI+ issue with storing PNG images on a non seek able stream, which seems to be fixed with Windows 7, I moved stream-handling specific "fixes" as far "down" as possible. By doing this we should have the best performance and can fix problems easier.
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2129 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
67852e0b76
commit
b600d72156
2 changed files with 31 additions and 17 deletions
|
@ -73,10 +73,14 @@ namespace GreenshotPlugin.Core {
|
|||
|
||||
/// <summary>
|
||||
/// Saves image to stream with specified quality
|
||||
/// To prevent problems with GDI version of before Windows 7:
|
||||
/// the stream is checked if it's seekable and if needed a MemoryStream as "cache" is used.
|
||||
/// </summary>
|
||||
public static void SaveToStream(Image imageToSave, Stream stream, OutputSettings outputSettings) {
|
||||
ImageFormat imageFormat = null;
|
||||
bool disposeImage = false;
|
||||
bool useMemoryStream = false;
|
||||
MemoryStream memoryStream = null;
|
||||
|
||||
switch (outputSettings.Format) {
|
||||
case OutputFormat.bmp:
|
||||
|
@ -88,13 +92,17 @@ namespace GreenshotPlugin.Core {
|
|||
case OutputFormat.jpg:
|
||||
imageFormat = ImageFormat.Jpeg;
|
||||
break;
|
||||
case OutputFormat.png:
|
||||
imageFormat = ImageFormat.Png;
|
||||
break;
|
||||
case OutputFormat.tiff:
|
||||
imageFormat = ImageFormat.Tiff;
|
||||
break;
|
||||
case OutputFormat.png:
|
||||
default:
|
||||
// Problem with non-seekable streams most likely doesn't happen with Windows 7 (OS Version 6.1 and later)
|
||||
// http://stackoverflow.com/questions/8349260/generic-gdi-error-on-one-machine-but-not-the-other
|
||||
if (!stream.CanSeek && (Environment.OSVersion.Version.Major < 6 || (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor == 1))) {
|
||||
useMemoryStream = true;
|
||||
LOG.Warn("Using memorystream prevent an issue with saving to a non seekable stream.");
|
||||
}
|
||||
imageFormat = ImageFormat.Png;
|
||||
break;
|
||||
}
|
||||
|
@ -139,20 +147,36 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
}
|
||||
LOG.DebugFormat("Saving image to stream with Format {0} and PixelFormat {1}", imageFormat, imageToSave.PixelFormat);
|
||||
|
||||
// Check if we want to use a memory stream, to prevent a issue which happens with Windows before "7".
|
||||
// The save is made to the targetStream, this is directed to either the MemoryStream or the original
|
||||
Stream targetStream = stream;
|
||||
if (useMemoryStream) {
|
||||
memoryStream = new MemoryStream();
|
||||
targetStream = memoryStream;
|
||||
}
|
||||
|
||||
if (imageFormat == ImageFormat.Jpeg) {
|
||||
EncoderParameters parameters = new EncoderParameters(1);
|
||||
parameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(Encoder.Quality, outputSettings.JPGQuality);
|
||||
ImageCodecInfo[] ies = ImageCodecInfo.GetImageEncoders();
|
||||
imageToSave.Save(stream, ies[1], parameters);
|
||||
imageToSave.Save(targetStream, ies[1], parameters);
|
||||
} else if (imageFormat != ImageFormat.Png && Image.IsAlphaPixelFormat(imageToSave.PixelFormat)) {
|
||||
// No transparency in target format
|
||||
using (Bitmap tmpBitmap = ImageHelper.Clone(imageToSave, PixelFormat.Format24bppRgb)) {
|
||||
tmpBitmap.Save(stream, imageFormat);
|
||||
tmpBitmap.Save(targetStream, imageFormat);
|
||||
}
|
||||
} else {
|
||||
imageToSave.Save(stream, imageFormat);
|
||||
imageToSave.Save(targetStream, imageFormat);
|
||||
}
|
||||
// If we used a memory stream, we need to stream the memory stream to the original stream.
|
||||
if (useMemoryStream) {
|
||||
memoryStream.WriteTo(stream);
|
||||
}
|
||||
} finally {
|
||||
if (memoryStream != null) {
|
||||
memoryStream.Dispose();
|
||||
}
|
||||
// cleanup if needed
|
||||
if (disposeImage && imageToSave != null) {
|
||||
imageToSave.Dispose();
|
||||
|
|
|
@ -415,17 +415,7 @@ namespace GreenshotPlugin.Core {
|
|||
"image/" + outputSettings.Format.ToString());
|
||||
|
||||
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
|
||||
|
||||
if (outputSettings.Format == OutputFormat.png) {
|
||||
// The PNG image formats need to be written to a seekable stream, so we need a intermediate MemoryStream
|
||||
using (MemoryStream memoryStream = new MemoryStream()) {
|
||||
ImageOutput.SaveToStream(image, memoryStream, outputSettings);
|
||||
memoryStream.WriteTo(formDataStream);
|
||||
}
|
||||
} else {
|
||||
ImageOutput.SaveToStream(image, formDataStream, outputSettings);
|
||||
}
|
||||
|
||||
ImageOutput.SaveToStream(image, formDataStream, outputSettings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue