mirror of
https://github.com/greenshot/greenshot
synced 2025-08-19 21:13:23 -07:00
Refactoring to prevent that the image for the clipboard is created multiple times. Code could most likely be cleaner and simpler but for now it should be okay.
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2401 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
efda1e3025
commit
09400ccdbe
2 changed files with 216 additions and 127 deletions
|
@ -22,6 +22,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -311,25 +312,43 @@ EndSelection:<<<<<<<4
|
||||||
try {
|
try {
|
||||||
MemoryStream imageStream = null;
|
MemoryStream imageStream = null;
|
||||||
|
|
||||||
if (!isValidStream(imageStream) && formats.Contains(FORMAT_PNG)) {
|
if (formats.Contains(FORMAT_PNG)) {
|
||||||
imageStream = GetFromDataObject(dataObject, FORMAT_PNG) as MemoryStream;
|
imageStream = GetFromDataObject(dataObject, FORMAT_PNG) as MemoryStream;
|
||||||
}
|
if (isValidStream(imageStream)) {
|
||||||
if (!isValidStream(imageStream) && formats.Contains(FORMAT_JPG)) {
|
try {
|
||||||
imageStream = GetFromDataObject(dataObject, FORMAT_JPG) as MemoryStream;
|
using (Image tmpImage = Image.FromStream(imageStream)) {
|
||||||
}
|
return ImageHelper.Clone(tmpImage);
|
||||||
if (!isValidStream(imageStream) && formats.Contains(DataFormats.Tiff)) {
|
}
|
||||||
imageStream = GetFromDataObject(dataObject, DataFormats.Tiff) as MemoryStream;
|
} catch (Exception streamImageEx) {
|
||||||
}
|
LOG.Error("Problem retrieving PNG image from clipboard.", streamImageEx);
|
||||||
|
|
||||||
if (isValidStream(imageStream)) {
|
|
||||||
try {
|
|
||||||
using (Image tmpImage = Image.FromStream(imageStream)) {
|
|
||||||
return ImageHelper.Clone(tmpImage);
|
|
||||||
}
|
}
|
||||||
} catch (Exception streamImageEx) {
|
|
||||||
LOG.Error("Problem retrieving Image from clipboard.", streamImageEx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (formats.Contains(FORMAT_JPG)) {
|
||||||
|
imageStream = GetFromDataObject(dataObject, FORMAT_JPG) as MemoryStream;
|
||||||
|
if (isValidStream(imageStream)) {
|
||||||
|
try {
|
||||||
|
using (Image tmpImage = Image.FromStream(imageStream)) {
|
||||||
|
return ImageHelper.Clone(tmpImage);
|
||||||
|
}
|
||||||
|
} catch (Exception streamImageEx) {
|
||||||
|
LOG.Error("Problem retrieving JPG image from clipboard.", streamImageEx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (formats.Contains(DataFormats.Tiff)) {
|
||||||
|
imageStream = GetFromDataObject(dataObject, DataFormats.Tiff) as MemoryStream;
|
||||||
|
if (isValidStream(imageStream)) {
|
||||||
|
try {
|
||||||
|
using (Image tmpImage = Image.FromStream(imageStream)) {
|
||||||
|
return ImageHelper.Clone(tmpImage);
|
||||||
|
}
|
||||||
|
} catch (Exception streamImageEx) {
|
||||||
|
LOG.Error("Problem retrieving TIFF image from clipboard.", streamImageEx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// the DIB readed should solve the issue reported here: https://sourceforge.net/projects/greenshot/forums/forum/676083/topic/6354353/index/page/1
|
// the DIB readed should solve the issue reported here: https://sourceforge.net/projects/greenshot/forums/forum/676083/topic/6354353/index/page/1
|
||||||
try {
|
try {
|
||||||
// If the EnableSpecialDIBClipboardReader flag in the config is set, use the code from:
|
// If the EnableSpecialDIBClipboardReader flag in the config is set, use the code from:
|
||||||
|
@ -466,14 +485,19 @@ EndSelection:<<<<<<<4
|
||||||
|
|
||||||
MemoryStream dibStream = null;
|
MemoryStream dibStream = null;
|
||||||
MemoryStream pngStream = null;
|
MemoryStream pngStream = null;
|
||||||
|
Image imageToSave = null;
|
||||||
|
bool disposeImage = false;
|
||||||
try {
|
try {
|
||||||
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false);
|
||||||
|
// Create the image which is going to be saved so we don't create it multiple times
|
||||||
|
disposeImage = ImageOutput.CreateImageFromSurface(surface, outputSettings, out imageToSave);
|
||||||
try {
|
try {
|
||||||
// Create PNG stream
|
// Create PNG stream
|
||||||
if (config.ClipboardFormats.Contains(ClipboardFormat.PNG)) {
|
if (config.ClipboardFormats.Contains(ClipboardFormat.PNG)) {
|
||||||
pngStream = new MemoryStream();
|
pngStream = new MemoryStream();
|
||||||
// PNG works for e.g. Powerpoint
|
// PNG works for e.g. Powerpoint
|
||||||
SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false);
|
SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false);
|
||||||
ImageOutput.SaveToStream(surface, pngStream, pngOutputSettings);
|
ImageOutput.SaveToStream(imageToSave, null, pngStream, pngOutputSettings);
|
||||||
pngStream.Seek(0, SeekOrigin.Begin);
|
pngStream.Seek(0, SeekOrigin.Begin);
|
||||||
// Set the PNG stream
|
// Set the PNG stream
|
||||||
ido.SetData(FORMAT_PNG, false, pngStream);
|
ido.SetData(FORMAT_PNG, false, pngStream);
|
||||||
|
@ -482,13 +506,12 @@ EndSelection:<<<<<<<4
|
||||||
LOG.Error("Error creating PNG for the Clipboard.", pngEX);
|
LOG.Error("Error creating PNG for the Clipboard.", pngEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (config.ClipboardFormats.Contains(ClipboardFormat.DIB)) {
|
if (config.ClipboardFormats.Contains(ClipboardFormat.DIB)) {
|
||||||
using (MemoryStream tmpBmpStream = new MemoryStream()) {
|
using (MemoryStream tmpBmpStream = new MemoryStream()) {
|
||||||
// Save image as BMP
|
// Save image as BMP
|
||||||
SurfaceOutputSettings bmpOutputSettings = new SurfaceOutputSettings(OutputFormat.bmp, 100, false);
|
SurfaceOutputSettings bmpOutputSettings = new SurfaceOutputSettings(OutputFormat.bmp, 100, false);
|
||||||
ImageOutput.SaveToStream(surface, tmpBmpStream, bmpOutputSettings);
|
ImageOutput.SaveToStream(imageToSave, null, tmpBmpStream, bmpOutputSettings);
|
||||||
|
|
||||||
dibStream = new MemoryStream();
|
dibStream = new MemoryStream();
|
||||||
// Copy the source, but skip the "BITMAPFILEHEADER" which has a size of 14
|
// Copy the source, but skip the "BITMAPFILEHEADER" which has a size of 14
|
||||||
|
@ -514,7 +537,12 @@ EndSelection:<<<<<<<4
|
||||||
// Do not allow to reduce the colors, some applications dislike 256 color images
|
// Do not allow to reduce the colors, some applications dislike 256 color images
|
||||||
// reported with bug #3594681
|
// reported with bug #3594681
|
||||||
pngOutputSettings.DisableReduceColors = true;
|
pngOutputSettings.DisableReduceColors = true;
|
||||||
ImageOutput.SaveToStream(surface, tmpPNGStream, pngOutputSettings);
|
// Check if we can use the previously used image
|
||||||
|
if (imageToSave.PixelFormat != PixelFormat.Format8bppIndexed) {
|
||||||
|
ImageOutput.SaveToStream(imageToSave, surface, tmpPNGStream, pngOutputSettings);
|
||||||
|
} else {
|
||||||
|
ImageOutput.SaveToStream(surface, tmpPNGStream, pngOutputSettings);
|
||||||
|
}
|
||||||
html = getHTMLDataURLString(surface, tmpPNGStream);
|
html = getHTMLDataURLString(surface, tmpPNGStream);
|
||||||
}
|
}
|
||||||
ido.SetText(html, TextDataFormat.Html);
|
ido.SetText(html, TextDataFormat.Html);
|
||||||
|
@ -523,11 +551,9 @@ EndSelection:<<<<<<<4
|
||||||
// we need to use the SetDataOject before the streams are closed otherwise the buffer will be gone!
|
// we need to use the SetDataOject before the streams are closed otherwise the buffer will be gone!
|
||||||
// Check if Bitmap is wanted
|
// Check if Bitmap is wanted
|
||||||
if (config.ClipboardFormats.Contains(ClipboardFormat.BITMAP)) {
|
if (config.ClipboardFormats.Contains(ClipboardFormat.BITMAP)) {
|
||||||
using (Image tmpImage = surface.GetImageForExport()) {
|
ido.SetImage(imageToSave);
|
||||||
ido.SetImage(tmpImage);
|
// Place the DataObject to the clipboard
|
||||||
// Place the DataObject to the clipboard
|
SetDataObject(ido, true);
|
||||||
SetDataObject(ido, true);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Place the DataObject to the clipboard
|
// Place the DataObject to the clipboard
|
||||||
SetDataObject(ido, true);
|
SetDataObject(ido, true);
|
||||||
|
@ -542,6 +568,10 @@ EndSelection:<<<<<<<4
|
||||||
dibStream.Dispose();
|
dibStream.Dispose();
|
||||||
dibStream = null;
|
dibStream = null;
|
||||||
}
|
}
|
||||||
|
// cleanup if needed
|
||||||
|
if (disposeImage && imageToSave != null) {
|
||||||
|
imageToSave.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,117 +69,65 @@ namespace GreenshotPlugin.Core {
|
||||||
return propertyItem;
|
return propertyItem;
|
||||||
}
|
}
|
||||||
#region save
|
#region save
|
||||||
|
/// <summary>
|
||||||
|
/// Saves ISurface to stream with specified output settings
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="surface">ISurface to save</param>
|
||||||
|
/// <param name="stream">Stream to save to</param>
|
||||||
|
/// <param name="outputSettings">SurfaceOutputSettings</param>
|
||||||
|
public static void SaveToStream(ISurface surface, Stream stream, SurfaceOutputSettings outputSettings) {
|
||||||
|
Image imageToSave = null;
|
||||||
|
bool disposeImage = CreateImageFromSurface(surface, outputSettings, out imageToSave);
|
||||||
|
SaveToStream(imageToSave, surface, stream, outputSettings);
|
||||||
|
// cleanup if needed
|
||||||
|
if (disposeImage && imageToSave != null) {
|
||||||
|
imageToSave.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves image to stream with specified quality
|
/// Saves image to stream with specified quality
|
||||||
/// To prevent problems with GDI version of before Windows 7:
|
/// 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.
|
/// the stream is checked if it's seekable and if needed a MemoryStream as "cache" is used.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SaveToStream(ISurface surface, Stream stream, SurfaceOutputSettings outputSettings) {
|
/// <param name="imageToSave">image to save</param>
|
||||||
|
/// <param name="surface">surface for the elements, if the greenshot format is used</param>
|
||||||
|
/// <param name="stream">Stream to save to</param>
|
||||||
|
/// <param name="outputSettings">SurfaceOutputSettings</param>
|
||||||
|
public static void SaveToStream(Image imageToSave, ISurface surface, Stream stream, SurfaceOutputSettings outputSettings) {
|
||||||
ImageFormat imageFormat = null;
|
ImageFormat imageFormat = null;
|
||||||
bool disposeImage = false;
|
|
||||||
bool useMemoryStream = false;
|
bool useMemoryStream = false;
|
||||||
MemoryStream memoryStream = null;
|
MemoryStream memoryStream = null;
|
||||||
|
|
||||||
switch (outputSettings.Format) {
|
|
||||||
case OutputFormat.bmp:
|
|
||||||
imageFormat = ImageFormat.Bmp;
|
|
||||||
break;
|
|
||||||
case OutputFormat.gif:
|
|
||||||
imageFormat = ImageFormat.Gif;
|
|
||||||
break;
|
|
||||||
case OutputFormat.jpg:
|
|
||||||
imageFormat = ImageFormat.Jpeg;
|
|
||||||
break;
|
|
||||||
case OutputFormat.tiff:
|
|
||||||
imageFormat = ImageFormat.Tiff;
|
|
||||||
break;
|
|
||||||
case OutputFormat.greenshot:
|
|
||||||
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) {
|
|
||||||
int majorVersion = Environment.OSVersion.Version.Major;
|
|
||||||
int minorVersion = Environment.OSVersion.Version.Minor;
|
|
||||||
if (majorVersion < 6 || (majorVersion == 6 && minorVersion == 0)) {
|
|
||||||
useMemoryStream = true;
|
|
||||||
LOG.Warn("Using memorystream prevent an issue with saving to a non seekable stream.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imageFormat = ImageFormat.Png;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check what image we want to save
|
|
||||||
Image imageToSave = null;
|
|
||||||
if (outputSettings.Format == OutputFormat.greenshot || outputSettings.SaveBackgroundOnly) {
|
|
||||||
// We save the image of the surface, this should not be disposed
|
|
||||||
imageToSave = surface.Image;
|
|
||||||
} else {
|
|
||||||
// We create the export image of the surface to save
|
|
||||||
imageToSave = surface.GetImageForExport();
|
|
||||||
disposeImage = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// The following block of modifications should be skipped when saving the greenshot format, no effects or otherwise!
|
switch (outputSettings.Format) {
|
||||||
if (outputSettings.Format != OutputFormat.greenshot) {
|
case OutputFormat.bmp:
|
||||||
Image tmpImage;
|
imageFormat = ImageFormat.Bmp;
|
||||||
if (outputSettings.Effects != null && outputSettings.Effects.Count > 0) {
|
break;
|
||||||
// apply effects, if there are any
|
case OutputFormat.gif:
|
||||||
Point ignoreOffset;
|
imageFormat = ImageFormat.Gif;
|
||||||
tmpImage = ImageHelper.ApplyEffects((Bitmap)imageToSave, outputSettings.Effects, out ignoreOffset);
|
break;
|
||||||
if (tmpImage != null) {
|
case OutputFormat.jpg:
|
||||||
if (disposeImage) {
|
imageFormat = ImageFormat.Jpeg;
|
||||||
imageToSave.Dispose();
|
break;
|
||||||
}
|
case OutputFormat.tiff:
|
||||||
imageToSave = tmpImage;
|
imageFormat = ImageFormat.Tiff;
|
||||||
disposeImage = true;
|
break;
|
||||||
}
|
case OutputFormat.greenshot:
|
||||||
}
|
case OutputFormat.png:
|
||||||
|
default:
|
||||||
// Removing transparency if it's not supported in the output
|
// Problem with non-seekable streams most likely doesn't happen with Windows 7 (OS Version 6.1 and later)
|
||||||
if (imageFormat != ImageFormat.Png && Image.IsAlphaPixelFormat(imageToSave.PixelFormat)) {
|
// http://stackoverflow.com/questions/8349260/generic-gdi-error-on-one-machine-but-not-the-other
|
||||||
Image nonAlphaImage = ImageHelper.Clone(imageToSave, PixelFormat.Format24bppRgb);
|
if (!stream.CanSeek) {
|
||||||
if (disposeImage) {
|
int majorVersion = Environment.OSVersion.Version.Major;
|
||||||
imageToSave.Dispose();
|
int minorVersion = Environment.OSVersion.Version.Minor;
|
||||||
}
|
if (majorVersion < 6 || (majorVersion == 6 && minorVersion == 0)) {
|
||||||
// Make sure the image is disposed!
|
useMemoryStream = true;
|
||||||
disposeImage = true;
|
LOG.Warn("Using memorystream prevent an issue with saving to a non seekable stream.");
|
||||||
imageToSave = nonAlphaImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for color reduction, forced or automatically, only when the DisableReduceColors is false
|
|
||||||
if (!outputSettings.DisableReduceColors && (conf.OutputFileAutoReduceColors || outputSettings.ReduceColors)) {
|
|
||||||
WuQuantizer quantizer = new WuQuantizer((Bitmap)imageToSave);
|
|
||||||
int colorCount = quantizer.GetColorCount();
|
|
||||||
LOG.InfoFormat("Image with format {0} has {1} colors", imageToSave.PixelFormat, colorCount);
|
|
||||||
if (outputSettings.ReduceColors || colorCount < 256) {
|
|
||||||
try {
|
|
||||||
LOG.Info("Reducing colors on bitmap to 255.");
|
|
||||||
tmpImage = quantizer.GetQuantizedImage(255);
|
|
||||||
if (disposeImage) {
|
|
||||||
imageToSave.Dispose();
|
|
||||||
}
|
|
||||||
imageToSave = tmpImage;
|
|
||||||
// Make sure the "new" image is disposed
|
|
||||||
disposeImage = true;
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG.Warn("Error occurred while Quantizing the image, ignoring and using original. Error: ", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
imageFormat = ImageFormat.Png;
|
||||||
|
break;
|
||||||
// Create meta-data
|
|
||||||
PropertyItem softwareUsedPropertyItem = CreatePropertyItem(PROPERTY_TAG_SOFTWARE_USED, "Greenshot");
|
|
||||||
if (softwareUsedPropertyItem != null) {
|
|
||||||
try {
|
|
||||||
imageToSave.SetPropertyItem(softwareUsedPropertyItem);
|
|
||||||
} catch (ArgumentException) {
|
|
||||||
LOG.WarnFormat("Image of type {0} do not support property {1}", imageFormat, softwareUsedPropertyItem.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
LOG.DebugFormat("Saving image to stream with Format {0} and PixelFormat {1}", imageFormat, imageToSave.PixelFormat);
|
LOG.DebugFormat("Saving image to stream with Format {0} and PixelFormat {1}", imageFormat, imageToSave.PixelFormat);
|
||||||
|
|
||||||
|
@ -197,7 +145,17 @@ namespace GreenshotPlugin.Core {
|
||||||
if (imageCodec.FormatID == imageFormat.Guid) {
|
if (imageCodec.FormatID == imageFormat.Guid) {
|
||||||
EncoderParameters parameters = new EncoderParameters(1);
|
EncoderParameters parameters = new EncoderParameters(1);
|
||||||
parameters.Param[0] = new EncoderParameter(Encoder.Quality, outputSettings.JPGQuality);
|
parameters.Param[0] = new EncoderParameter(Encoder.Quality, outputSettings.JPGQuality);
|
||||||
imageToSave.Save(targetStream, imageCodec, parameters);
|
// Removing transparency if it's not supported in the output
|
||||||
|
if (Image.IsAlphaPixelFormat(imageToSave.PixelFormat)) {
|
||||||
|
Image nonAlphaImage = ImageHelper.Clone(imageToSave, PixelFormat.Format24bppRgb);
|
||||||
|
AddTag(nonAlphaImage);
|
||||||
|
nonAlphaImage.Save(targetStream, imageCodec, parameters);
|
||||||
|
nonAlphaImage.Dispose();
|
||||||
|
nonAlphaImage = null;
|
||||||
|
} else {
|
||||||
|
AddTag(imageToSave);
|
||||||
|
imageToSave.Save(targetStream, imageCodec, parameters);
|
||||||
|
}
|
||||||
foundEncoder = true;
|
foundEncoder = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -206,7 +164,17 @@ namespace GreenshotPlugin.Core {
|
||||||
throw new ApplicationException("No JPG encoder found, this should not happen.");
|
throw new ApplicationException("No JPG encoder found, this should not happen.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
imageToSave.Save(targetStream, imageFormat);
|
// Removing transparency if it's not supported in the output
|
||||||
|
if (imageFormat != ImageFormat.Png && Image.IsAlphaPixelFormat(imageToSave.PixelFormat)) {
|
||||||
|
Image nonAlphaImage = ImageHelper.Clone(imageToSave, PixelFormat.Format24bppRgb);
|
||||||
|
AddTag(nonAlphaImage);
|
||||||
|
nonAlphaImage.Save(targetStream, imageFormat);
|
||||||
|
nonAlphaImage.Dispose();
|
||||||
|
nonAlphaImage = null;
|
||||||
|
} else {
|
||||||
|
AddTag(imageToSave);
|
||||||
|
imageToSave.Save(targetStream, imageFormat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we used a memory stream, we need to stream the memory stream to the original stream.
|
// If we used a memory stream, we need to stream the memory stream to the original stream.
|
||||||
|
@ -231,9 +199,100 @@ namespace GreenshotPlugin.Core {
|
||||||
if (memoryStream != null) {
|
if (memoryStream != null) {
|
||||||
memoryStream.Dispose();
|
memoryStream.Dispose();
|
||||||
}
|
}
|
||||||
// cleanup if needed
|
}
|
||||||
if (disposeImage && imageToSave != null) {
|
}
|
||||||
imageToSave.Dispose();
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create an image from a surface with the settings from the output settings applied
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="surface"></param>
|
||||||
|
/// <param name="outputSettings"></param>
|
||||||
|
/// <param name="imageToSave"></param>
|
||||||
|
/// <returns>true if the image must be disposed</returns>
|
||||||
|
public static bool CreateImageFromSurface(ISurface surface, SurfaceOutputSettings outputSettings, out Image imageToSave) {
|
||||||
|
bool disposeImage = false;
|
||||||
|
ImageFormat imageFormat = null;
|
||||||
|
switch (outputSettings.Format) {
|
||||||
|
case OutputFormat.bmp:
|
||||||
|
imageFormat = ImageFormat.Bmp;
|
||||||
|
break;
|
||||||
|
case OutputFormat.gif:
|
||||||
|
imageFormat = ImageFormat.Gif;
|
||||||
|
break;
|
||||||
|
case OutputFormat.jpg:
|
||||||
|
imageFormat = ImageFormat.Jpeg;
|
||||||
|
break;
|
||||||
|
case OutputFormat.tiff:
|
||||||
|
imageFormat = ImageFormat.Tiff;
|
||||||
|
break;
|
||||||
|
case OutputFormat.greenshot:
|
||||||
|
case OutputFormat.png:
|
||||||
|
default:
|
||||||
|
imageFormat = ImageFormat.Png;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputSettings.Format == OutputFormat.greenshot || outputSettings.SaveBackgroundOnly) {
|
||||||
|
// We save the image of the surface, this should not be disposed
|
||||||
|
imageToSave = surface.Image;
|
||||||
|
} else {
|
||||||
|
// We create the export image of the surface to save
|
||||||
|
imageToSave = surface.GetImageForExport();
|
||||||
|
disposeImage = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following block of modifications should be skipped when saving the greenshot format, no effects or otherwise!
|
||||||
|
if (outputSettings.Format != OutputFormat.greenshot) {
|
||||||
|
Image tmpImage;
|
||||||
|
if (outputSettings.Effects != null && outputSettings.Effects.Count > 0) {
|
||||||
|
// apply effects, if there are any
|
||||||
|
Point ignoreOffset;
|
||||||
|
tmpImage = ImageHelper.ApplyEffects((Bitmap)imageToSave, outputSettings.Effects, out ignoreOffset);
|
||||||
|
if (tmpImage != null) {
|
||||||
|
if (disposeImage) {
|
||||||
|
imageToSave.Dispose();
|
||||||
|
}
|
||||||
|
imageToSave = tmpImage;
|
||||||
|
disposeImage = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for color reduction, forced or automatically, only when the DisableReduceColors is false
|
||||||
|
if (!outputSettings.DisableReduceColors && (conf.OutputFileAutoReduceColors || outputSettings.ReduceColors)) {
|
||||||
|
WuQuantizer quantizer = new WuQuantizer((Bitmap)imageToSave);
|
||||||
|
int colorCount = quantizer.GetColorCount();
|
||||||
|
LOG.InfoFormat("Image with format {0} has {1} colors", imageToSave.PixelFormat, colorCount);
|
||||||
|
if (outputSettings.ReduceColors || colorCount < 256) {
|
||||||
|
try {
|
||||||
|
LOG.Info("Reducing colors on bitmap to 255.");
|
||||||
|
tmpImage = quantizer.GetQuantizedImage(255);
|
||||||
|
if (disposeImage) {
|
||||||
|
imageToSave.Dispose();
|
||||||
|
}
|
||||||
|
imageToSave = tmpImage;
|
||||||
|
// Make sure the "new" image is disposed
|
||||||
|
disposeImage = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.Warn("Error occurred while Quantizing the image, ignoring and using original. Error: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return disposeImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add the greenshot property!
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="imageToSave"></param>
|
||||||
|
private static void AddTag(Image imageToSave) {
|
||||||
|
// Create meta-data
|
||||||
|
PropertyItem softwareUsedPropertyItem = CreatePropertyItem(PROPERTY_TAG_SOFTWARE_USED, "Greenshot");
|
||||||
|
if (softwareUsedPropertyItem != null) {
|
||||||
|
try {
|
||||||
|
imageToSave.SetPropertyItem(softwareUsedPropertyItem);
|
||||||
|
} catch (Exception) {
|
||||||
|
LOG.WarnFormat("Couldn't set property {0}", softwareUsedPropertyItem.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue