Applied my "patch" which refactors the complete codebase to have IEffect support, this is an interface which can be used to supply effects to a bitmap. These effects can now be passed to the OutputSettings (which now is called SurfaceOutputSettings) to control how the output is modified. This is very useful for e.g. OCR which needs a grayscale & resized image.

git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2377 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
RKrom 2012-12-12 09:51:41 +00:00
commit 0c7e16a771
33 changed files with 212 additions and 148 deletions

View file

@ -388,7 +388,7 @@ EndSelection:<<<<<<<4
if (config.ClipboardFormats.Contains(ClipboardFormat.PNG) || config.ClipboardFormats.Contains(ClipboardFormat.HTMLDATAURL)) {
pngStream = new MemoryStream();
// PNG works for Powerpoint
OutputSettings pngOutputSettings = new OutputSettings(OutputFormat.png, 100, false);
SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false);
ImageOutput.SaveToStream(surface, pngStream, pngOutputSettings);
pngStream.Seek(0, SeekOrigin.Begin);
}
@ -401,7 +401,7 @@ EndSelection:<<<<<<<4
if (config.ClipboardFormats.Contains(ClipboardFormat.DIB)) {
bmpStream = new MemoryStream();
// Save image as BMP
OutputSettings bmpOutputSettings = new OutputSettings(OutputFormat.bmp, 100, false);
SurfaceOutputSettings bmpOutputSettings = new SurfaceOutputSettings(OutputFormat.bmp, 100, false);
ImageOutput.SaveToStream(surface, bmpStream, bmpOutputSettings);
imageStream = new MemoryStream();
@ -414,7 +414,7 @@ EndSelection:<<<<<<<4
// Set the HTML
if (config.ClipboardFormats.Contains(ClipboardFormat.HTML)) {
string tmpFile = ImageOutput.SaveToTmpFile(surface, new OutputSettings(OutputFormat.png), null);
string tmpFile = ImageOutput.SaveToTmpFile(surface, new SurfaceOutputSettings(OutputFormat.png), null);
string html = getHTMLString(surface, tmpFile);
ido.SetText(html, TextDataFormat.Html);
} else if (config.ClipboardFormats.Contains(ClipboardFormat.HTMLDATAURL)) {

View file

@ -27,6 +27,8 @@ using System.IO;
using System.Runtime.InteropServices;
using Greenshot.IniFile;
using GreenshotPlugin.UnmanagedHelpers;
using Greenshot.Plugin;
using Greenshot.Core;
namespace GreenshotPlugin.Core {
/// <summary>
@ -36,9 +38,26 @@ namespace GreenshotPlugin.Core {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ImageHelper));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
/// <summary>
/// Create a thumbnail from an image
/// </summary>
/// <param name="image"></param>
/// <param name="thumbWidth"></param>
/// <param name="thumbHeight"></param>
/// <returns></returns>
public static Image CreateThumbnail(Image image, int thumbWidth, int thumbHeight) {
return CreateThumbnail(image, thumbWidth, thumbHeight, -1, -1);
}
/// <summary>
/// Create a Thumbnail
/// </summary>
/// <param name="image"></param>
/// <param name="thumbWidth"></param>
/// <param name="thumbHeight"></param>
/// <param name="maxWidth"></param>
/// <param name="maxHeight"></param>
/// <returns></returns>
public static Image CreateThumbnail(Image image, int thumbWidth, int thumbHeight, int maxWidth, int maxHeight) {
int srcWidth=image.Width;
int srcHeight=image.Height;
@ -90,11 +109,11 @@ namespace GreenshotPlugin.Core {
}
/// <summary>
/// Helper method for the FindAutoCropRectangle
/// Private helper method for the FindAutoCropRectangle
/// </summary>
/// <param name="buffer"></param>
/// <param name="colorPoint"></param>
/// <returns></returns>
/// <returns>Rectangle</returns>
private static Rectangle FindAutoCropRectangle(BitmapBuffer buffer, Point colorPoint, int cropDifference) {
Rectangle cropRectangle = Rectangle.Empty;
Color referenceColor = buffer.GetColorAtWithoutAlpha(colorPoint.X,colorPoint.Y);
@ -225,19 +244,15 @@ namespace GreenshotPlugin.Core {
}
return fileBitmap;
}
/**
* Checks if we support the supplied PixelFormat
*/
private static bool isSupported(PixelFormat pixelformat) {
return (PixelFormat.Format32bppArgb.Equals(pixelformat)||
PixelFormat.Format32bppRgb.Equals(pixelformat) ||
PixelFormat.Format24bppRgb.Equals(pixelformat));
}
// Based on: http://www.codeproject.com/KB/cs/IconExtractor.aspx
// And a hint from: http://www.codeproject.com/KB/cs/IconLib.aspx
public static Bitmap ExtractVistaIcon(Stream iconStream) {
/// <summary>
/// Based on: http://www.codeproject.com/KB/cs/IconExtractor.aspx
/// And a hint from: http://www.codeproject.com/KB/cs/IconLib.aspx
/// </summary>
/// <param name="iconStream">Stream with the icon information</param>
/// <returns>Bitmap with the Vista Icon (256x256)</returns>
private static Bitmap ExtractVistaIcon(Stream iconStream) {
const int SizeICONDIR = 6;
const int SizeICONDIRENTRY = 16;
Bitmap bmpPngExtracted = null;
@ -315,6 +330,44 @@ namespace GreenshotPlugin.Core {
return Shell32.ExtractIconEx(location, -1, out large, out small, 0);
}
/// <summary>
/// Apply the effect to the bitmap
/// </summary>
/// <param name="sourceBitmap">Bitmap</param>
/// <param name="effect">IEffect</param>
/// <returns>Bitmap</returns>
public static Bitmap ApplyEffect(Bitmap sourceBitmap, IEffect effect, out Point offset) {
List<IEffect> effects = new List<IEffect>();
effects.Add(effect);
return ApplyEffects(sourceBitmap, effects, out offset);
}
/// <summary>
/// Apply the effects in the supplied order to the bitmap
/// </summary>
/// <param name="sourceBitmap">Bitmap</param>
/// <param name="effects">List<IEffect></param>
/// <returns>Bitmap</returns>
public static Bitmap ApplyEffects(Bitmap sourceBitmap, List<IEffect> effects, out Point offset) {
Bitmap currentBitmap = sourceBitmap;
bool disposeImage = false;
// Default out value for the offset, will be modified there where needed
offset = new Point(0, 0);
Point tmpPoint;
Bitmap tmpBitmap = null;
foreach (IEffect effect in effects) {
tmpBitmap = effect.Apply(currentBitmap, out tmpPoint);
offset.Offset(tmpPoint);
if (disposeImage) {
currentBitmap.Dispose();
}
currentBitmap = tmpBitmap;
// Make sure the "new" image is disposed
disposeImage = true;
}
return tmpBitmap;
}
/// <summary>
/// Make the picture look like it's torn
/// </summary>
@ -843,9 +896,10 @@ namespace GreenshotPlugin.Core {
/// <param name="targetPixelformat">What pixel format must the returning bitmap have</param>
/// <param name="offset">How many pixels is the original image moved?</param>
/// <returns>Bitmap with the shadow, is bigger than the sourceBitmap!!</returns>
public static Bitmap CreateShadow(Image sourceBitmap, float darkness, int shadowSize, ref Point offset, PixelFormat targetPixelformat) {
public static Bitmap CreateShadow(Image sourceBitmap, float darkness, int shadowSize, Point shadowOffset, out Point offset, PixelFormat targetPixelformat) {
// Create a new "clean" image
Bitmap returnImage = null;
offset = shadowOffset;
offset.X += shadowSize - 1;
offset.Y += shadowSize - 1;
using (Bitmap tmpImage = CreateEmpty(sourceBitmap.Width + (shadowSize * 2), sourceBitmap.Height + (shadowSize * 2), targetPixelformat, Color.Empty, sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution)) {
@ -958,9 +1012,16 @@ namespace GreenshotPlugin.Core {
/// <returns>Bitmap with grayscale</returns>
public static Bitmap CreateGrayscale(Bitmap sourceBitmap) {
//create a blank bitmap the same size as original
Bitmap newBitmap = CreateEmptyLike(sourceBitmap, Color.Empty);
// If using 8bpp than the following exception comes: A Graphics object cannot be created from an image that has an indexed pixel format.
Bitmap newBitmap = CreateEmpty(sourceBitmap.Width, sourceBitmap.Height, PixelFormat.Format24bppRgb, Color.Empty, sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution);
//ColorPalette imagePalette = newBitmap.Palette;
//for (int i = 0; i <= 255; i++) {
// // create greyscale color table
// imagePalette.Entries[i] = Color.FromArgb(i, i, i);
//}
//newBitmap.Palette = imagePalette;
//get a graphics object from the new image
// get a graphics object from the new image
using (Graphics graphics = Graphics.FromImage(newBitmap)) {
// create the grayscale ColorMatrix
ColorMatrix colorMatrix = new ColorMatrix(

View file

@ -28,6 +28,7 @@ using System.Windows.Forms;
using Greenshot.IniFile;
using Greenshot.Plugin;
using GreenshotPlugin.Controls;
using Greenshot.Core;
namespace GreenshotPlugin.Core {
/// <summary>
@ -74,7 +75,7 @@ namespace GreenshotPlugin.Core {
/// 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(ISurface surface, Stream stream, OutputSettings outputSettings) {
public static void SaveToStream(ISurface surface, Stream stream, SurfaceOutputSettings outputSettings) {
ImageFormat imageFormat = null;
bool disposeImage = false;
bool useMemoryStream = false;
@ -112,7 +113,7 @@ namespace GreenshotPlugin.Core {
// check what image we want to save
Image imageToSave = null;
if (outputSettings.Format == OutputFormat.greenshot) {
if (outputSettings.Format == OutputFormat.greenshot || outputSettings.SaveBackgroundOnly) {
// We save the image of the surface, this should not be disposed
imageToSave = surface.Image;
} else {
@ -122,7 +123,18 @@ namespace GreenshotPlugin.Core {
}
try {
// Removing transparency if it's not supported
// apply effects, if there are any
Point ignoreOffset;
Image tmpImage = ImageHelper.ApplyEffects((Bitmap)imageToSave, outputSettings.Effects, out ignoreOffset);
if (tmpImage != null) {
if (disposeImage) {
imageToSave.Dispose();
}
imageToSave = tmpImage;
disposeImage = true;
}
// 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);
if (disposeImage) {
@ -141,7 +153,7 @@ namespace GreenshotPlugin.Core {
if (outputSettings.ReduceColors || colorCount < 256) {
try {
LOG.Info("Reducing colors on bitmap to 255.");
Image tmpImage = quantizer.GetQuantizedImage(255);
tmpImage = quantizer.GetQuantizedImage(255);
if (disposeImage) {
imageToSave.Dispose();
}
@ -152,8 +164,6 @@ namespace GreenshotPlugin.Core {
LOG.Warn("Error occurred while Quantizing the image, ignoring and using original. Error: ", e);
}
}
} else {
LOG.Info("Skipping color reduction test, OutputFileAutoReduceColors is set to false.");
}
// Create meta-data
@ -273,7 +283,7 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Saves image to specific path with specified quality
/// </summary>
public static void Save(ISurface surface, string fullPath, bool allowOverwrite, OutputSettings outputSettings, bool copyPathToClipboard) {
public static void Save(ISurface surface, string fullPath, bool allowOverwrite, SurfaceOutputSettings outputSettings, bool copyPathToClipboard) {
fullPath = FilenameHelper.MakeFQFilenameSafe(fullPath);
string path = Path.GetDirectoryName(fullPath);
@ -334,7 +344,7 @@ namespace GreenshotPlugin.Core {
if (dialogResult.Equals(DialogResult.OK)) {
try {
string fileNameWithExtension = saveImageFileDialog.FileNameWithExtension;
OutputSettings outputSettings = new OutputSettings(FormatForFilename(fileNameWithExtension));
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(FormatForFilename(fileNameWithExtension));
if (conf.OutputFilePromptQuality) {
QualityDialog qualityDialog = new QualityDialog(outputSettings);
qualityDialog.ShowDialog();
@ -360,7 +370,7 @@ namespace GreenshotPlugin.Core {
/// <param name="captureDetails"></param>
/// <param name="outputSettings"></param>
/// <returns>Path to image file</returns>
public static string SaveNamedTmpFile(ISurface surface, ICaptureDetails captureDetails, OutputSettings outputSettings) {
public static string SaveNamedTmpFile(ISurface surface, ICaptureDetails captureDetails, SurfaceOutputSettings outputSettings) {
string pattern = conf.OutputFileFilenamePattern;
if (pattern == null || string.IsNullOrEmpty(pattern.Trim())) {
pattern = "greenshot ${capturetime}";
@ -393,7 +403,7 @@ namespace GreenshotPlugin.Core {
/// </summary>
/// <param name="image"></param>
/// <returns></returns>
public static string SaveToTmpFile(ISurface surface, OutputSettings outputSettings, string destinationPath) {
public static string SaveToTmpFile(ISurface surface, SurfaceOutputSettings outputSettings, string destinationPath) {
string tmpFile = Path.GetRandomFileName() + "." + outputSettings.Format.ToString();
// Prevent problems with "other characters", which could cause problems
tmpFile = Regex.Replace(tmpFile, @"[^\d\w\.]", "");

View file

@ -415,10 +415,10 @@ namespace GreenshotPlugin.Core {
/// </summary>
public class SurfaceContainer : IBinaryContainer {
private ISurface surface;
private OutputSettings outputSettings;
private SurfaceOutputSettings outputSettings;
private string fileName;
public SurfaceContainer(ISurface surface, OutputSettings outputSettings, string filename) {
public SurfaceContainer(ISurface surface, SurfaceOutputSettings outputSettings, string filename) {
this.surface = surface;
this.outputSettings = outputSettings;
this.fileName = filename;