mirror of
https://github.com/greenshot/greenshot
synced 2025-07-30 11:40:40 -07:00
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:
parent
5541e2e1c7
commit
0c7e16a771
33 changed files with 212 additions and 148 deletions
|
@ -76,7 +76,7 @@ namespace Greenshot.Destinations {
|
||||||
bool overwrite;
|
bool overwrite;
|
||||||
string fullPath;
|
string fullPath;
|
||||||
// Get output settings from the configuration
|
// Get output settings from the configuration
|
||||||
OutputSettings outputSettings = new OutputSettings();
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings();
|
||||||
|
|
||||||
if (captureDetails != null && captureDetails.Filename != null) {
|
if (captureDetails != null && captureDetails.Filename != null) {
|
||||||
// As we save a pre-selected file, allow to overwrite.
|
// As we save a pre-selected file, allow to overwrite.
|
||||||
|
|
|
@ -29,6 +29,7 @@ using Greenshot.Helpers;
|
||||||
using Greenshot.Plugin.Drawing;
|
using Greenshot.Plugin.Drawing;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
|
using Greenshot.Core;
|
||||||
|
|
||||||
namespace Greenshot.Drawing {
|
namespace Greenshot.Drawing {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -91,13 +92,8 @@ namespace Greenshot.Drawing {
|
||||||
|
|
||||||
public Bitmap Bitmap {
|
public Bitmap Bitmap {
|
||||||
set {
|
set {
|
||||||
if (bitmap != null) {
|
// Remove all current bitmaps
|
||||||
bitmap.Dispose();
|
Dispose(true);
|
||||||
}
|
|
||||||
if (shadowBitmap != null) {
|
|
||||||
shadowBitmap.Dispose();
|
|
||||||
shadowBitmap = null;
|
|
||||||
}
|
|
||||||
bitmap = ImageHelper.Clone(value);
|
bitmap = ImageHelper.Clone(value);
|
||||||
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
||||||
CheckShadow(shadow);
|
CheckShadow(shadow);
|
||||||
|
@ -114,29 +110,29 @@ namespace Greenshot.Drawing {
|
||||||
get { return bitmap; }
|
get { return bitmap; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Destructor
|
/// Destructor
|
||||||
*/
|
/// </summary>
|
||||||
~BitmapContainer() {
|
~BitmapContainer() {
|
||||||
Dispose(false);
|
Dispose(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* The public accessible Dispose
|
/// The public accessible Dispose
|
||||||
* Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
|
/// Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
|
||||||
*/
|
/// </summary>
|
||||||
public new void Dispose() {
|
public new void Dispose() {
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The bulk of the clean-up code is implemented in Dispose(bool)
|
/// <summary>
|
||||||
|
/// The bulk of the clean-up code is implemented in Dispose(bool)
|
||||||
/**
|
/// This Dispose is called from the Dispose and the Destructor.
|
||||||
* This Dispose is called from the Dispose and the Destructor.
|
/// When disposing==true all non-managed resources should be freed too!
|
||||||
* When disposing==true all non-managed resources should be freed too!
|
/// </summary>
|
||||||
*/
|
/// <param name="disposing"></param>
|
||||||
protected virtual void Dispose(bool disposing) {
|
protected virtual void Dispose(bool disposing) {
|
||||||
if (disposing) {
|
if (disposing) {
|
||||||
if (bitmap != null) {
|
if (bitmap != null) {
|
||||||
|
@ -150,6 +146,10 @@ namespace Greenshot.Drawing {
|
||||||
shadowBitmap = null;
|
shadowBitmap = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename"></param>
|
||||||
public void Load(string filename) {
|
public void Load(string filename) {
|
||||||
if (File.Exists(filename)) {
|
if (File.Exists(filename)) {
|
||||||
// Always make sure ImageHelper.LoadBitmap results are disposed some time,
|
// Always make sure ImageHelper.LoadBitmap results are disposed some time,
|
||||||
|
@ -161,21 +161,35 @@ namespace Greenshot.Drawing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rotate the bitmap
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rotateFlipType"></param>
|
||||||
public override void Rotate(RotateFlipType rotateFlipType) {
|
public override void Rotate(RotateFlipType rotateFlipType) {
|
||||||
Bitmap newBitmap = ImageHelper.RotateFlip((Bitmap)bitmap, rotateFlipType);
|
Bitmap newBitmap = ImageHelper.RotateFlip((Bitmap)bitmap, rotateFlipType);
|
||||||
if (bitmap != null) {
|
if (newBitmap != null) {
|
||||||
bitmap.Dispose();
|
// Remove all current bitmaps, also the shadow (will be recreated)
|
||||||
|
Dispose(true);
|
||||||
|
bitmap = newBitmap;
|
||||||
}
|
}
|
||||||
bitmap = newBitmap;
|
|
||||||
base.Rotate(rotateFlipType);
|
base.Rotate(rotateFlipType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This checks if a shadow is already generated
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shadow"></param>
|
||||||
private void CheckShadow(bool shadow) {
|
private void CheckShadow(bool shadow) {
|
||||||
if (shadow && shadowBitmap == null) {
|
if (shadow && shadowBitmap == null) {
|
||||||
shadowBitmap = ImageHelper.CreateShadow(bitmap, 1f, 6, ref shadowOffset, PixelFormat.Format32bppArgb);
|
shadowBitmap = ImageHelper.ApplyEffect(bitmap, new DropShadowEffect(), out shadowOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draw the actual container to the graphics object
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="graphics"></param>
|
||||||
|
/// <param name="rm"></param>
|
||||||
public override void Draw(Graphics graphics, RenderMode rm) {
|
public override void Draw(Graphics graphics, RenderMode rm) {
|
||||||
if (bitmap != null) {
|
if (bitmap != null) {
|
||||||
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
||||||
|
|
|
@ -37,6 +37,7 @@ using Greenshot.IniFile;
|
||||||
using Greenshot.Drawing.Filters;
|
using Greenshot.Drawing.Filters;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
|
using Greenshot.Core;
|
||||||
|
|
||||||
namespace Greenshot.Drawing {
|
namespace Greenshot.Drawing {
|
||||||
|
|
||||||
|
@ -896,61 +897,14 @@ namespace Greenshot.Drawing {
|
||||||
/// Apply a bitmap effect to the surface
|
/// Apply a bitmap effect to the surface
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="effect"></param>
|
/// <param name="effect"></param>
|
||||||
public void ApplyBitmapEffect(Effects effect) {
|
public void ApplyBitmapEffect(IEffect effect) {
|
||||||
BackgroundForm backgroundForm = new BackgroundForm("Effect", "Please wait");
|
BackgroundForm backgroundForm = new BackgroundForm("Effect", "Please wait");
|
||||||
backgroundForm.Show();
|
backgroundForm.Show();
|
||||||
Application.DoEvents();
|
Application.DoEvents();
|
||||||
try {
|
try {
|
||||||
Rectangle imageRectangle = new Rectangle(Point.Empty, Image.Size);
|
Rectangle imageRectangle = new Rectangle(Point.Empty, Image.Size);
|
||||||
Bitmap newImage = null;
|
Point offset;
|
||||||
Point offset = new Point(-1,-1);
|
Bitmap newImage = ImageHelper.ApplyEffect((Bitmap)Image, effect, out offset);
|
||||||
switch (effect) {
|
|
||||||
case Effects.Shadow:
|
|
||||||
newImage = ImageHelper.CreateShadow((Bitmap)Image, 1f, 9, ref offset, PixelFormat.Format32bppArgb); //Image.PixelFormat);
|
|
||||||
break;
|
|
||||||
case Effects.TornEdge:
|
|
||||||
using (Bitmap tmpImage = ImageHelper.CreateTornEdge((Bitmap)Image)) {
|
|
||||||
newImage = ImageHelper.CreateShadow(tmpImage, 1f, 7, ref offset, PixelFormat.Format32bppArgb); //Image.PixelFormat);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Effects.Border:
|
|
||||||
newImage = ImageHelper.CreateBorder((Bitmap)Image, 2, Color.Black, Image.PixelFormat, out offset);
|
|
||||||
break;
|
|
||||||
case Effects.Grayscale:
|
|
||||||
newImage = ImageHelper.CreateGrayscale((Bitmap)Image);
|
|
||||||
break;
|
|
||||||
case Effects.Invert:
|
|
||||||
newImage = ImageHelper.CreateNegative((Bitmap)Image);
|
|
||||||
break;
|
|
||||||
case Effects.RotateClockwise:
|
|
||||||
case Effects.RotateCounterClockwise:
|
|
||||||
RotateFlipType rotateFlipType = RotateFlipType.Rotate270FlipNone;
|
|
||||||
if (effect == Effects.RotateClockwise) {
|
|
||||||
rotateFlipType = RotateFlipType.Rotate90FlipNone;
|
|
||||||
}
|
|
||||||
// Do not rotate the drawable containers until this works!
|
|
||||||
//MakeUndoable(new DrawableContainerBoundsChangeMemento(elements.AsIDrawableContainerList()), false);
|
|
||||||
//foreach (DrawableContainer drawableContainer in elements) {
|
|
||||||
// if (drawableContainer.CanRotate) {
|
|
||||||
// drawableContainer.Rotate(rotateFlipType);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
newImage = ImageHelper.RotateFlip((Bitmap)Image, rotateFlipType);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// The following was added to correct any unneeded pixels, had the bad effect that sometimes everything was cropped... :(
|
|
||||||
//Rectangle autoCropRectangle = ImageHelper.FindAutoCropRectangle(newImage, 0);
|
|
||||||
//if (!Size.Empty.Equals(autoCropRectangle.Size) && !autoCropRectangle.Size.Equals(newImage.Size)) {
|
|
||||||
// LOG.InfoFormat("Crop to {0}", autoCropRectangle);
|
|
||||||
// using (Bitmap tmpImage = newImage) {
|
|
||||||
// newImage = ImageHelper.CloneArea(newImage, autoCropRectangle, PixelFormat.DontCare);
|
|
||||||
// }
|
|
||||||
// // Fix offset
|
|
||||||
// offset = new Point(offset.X - autoCropRectangle.X, offset.Y - autoCropRectangle.Y);
|
|
||||||
//} else {
|
|
||||||
// LOG.DebugFormat("No cropping needed!");
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (newImage != null) {
|
if (newImage != null) {
|
||||||
// Make sure the elements move according to the offset the effect made the bitmap move
|
// Make sure the elements move according to the offset the effect made the bitmap move
|
||||||
elements.MoveBy(offset.X, offset.Y);
|
elements.MoveBy(offset.X, offset.Y);
|
||||||
|
|
|
@ -41,6 +41,7 @@ using Greenshot.IniFile;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using Greenshot.Plugin.Drawing;
|
using Greenshot.Plugin.Drawing;
|
||||||
|
using Greenshot.Core;
|
||||||
|
|
||||||
namespace Greenshot {
|
namespace Greenshot {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1198,22 +1199,22 @@ namespace Greenshot {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddBorderToolStripMenuItemClick(object sender, EventArgs e) {
|
void AddBorderToolStripMenuItemClick(object sender, EventArgs e) {
|
||||||
surface.ApplyBitmapEffect(Effects.Border);
|
surface.ApplyBitmapEffect(new BorderEffect());
|
||||||
updateUndoRedoSurfaceDependencies();
|
updateUndoRedoSurfaceDependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddDropshadowToolStripMenuItemClick(object sender, EventArgs e) {
|
void AddDropshadowToolStripMenuItemClick(object sender, EventArgs e) {
|
||||||
surface.ApplyBitmapEffect(Effects.Shadow);
|
surface.ApplyBitmapEffect(new DropShadowEffect());
|
||||||
updateUndoRedoSurfaceDependencies();
|
updateUndoRedoSurfaceDependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TornEdgesToolStripMenuItemClick(object sender, EventArgs e) {
|
void TornEdgesToolStripMenuItemClick(object sender, EventArgs e) {
|
||||||
surface.ApplyBitmapEffect(Effects.TornEdge);
|
surface.ApplyBitmapEffect(new TornEdgeEffect());
|
||||||
updateUndoRedoSurfaceDependencies();
|
updateUndoRedoSurfaceDependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrayscaleToolStripMenuItemClick(object sender, EventArgs e) {
|
void GrayscaleToolStripMenuItemClick(object sender, EventArgs e) {
|
||||||
surface.ApplyBitmapEffect(Effects.Grayscale);
|
surface.ApplyBitmapEffect(new GrayscaleEffect());
|
||||||
updateUndoRedoSurfaceDependencies();
|
updateUndoRedoSurfaceDependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1223,17 +1224,17 @@ namespace Greenshot {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RotateCwToolstripButtonClick(object sender, EventArgs e) {
|
void RotateCwToolstripButtonClick(object sender, EventArgs e) {
|
||||||
surface.ApplyBitmapEffect(Effects.RotateClockwise);
|
surface.ApplyBitmapEffect(new RotateEffect(90));
|
||||||
updateUndoRedoSurfaceDependencies();
|
updateUndoRedoSurfaceDependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RotateCcwToolstripButtonClick(object sender, EventArgs e) {
|
void RotateCcwToolstripButtonClick(object sender, EventArgs e) {
|
||||||
surface.ApplyBitmapEffect(Effects.RotateCounterClockwise);
|
surface.ApplyBitmapEffect(new RotateEffect(270));
|
||||||
updateUndoRedoSurfaceDependencies();
|
updateUndoRedoSurfaceDependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InvertToolStripMenuItemClick(object sender, EventArgs e) {
|
void InvertToolStripMenuItemClick(object sender, EventArgs e) {
|
||||||
surface.ApplyBitmapEffect(Effects.Invert);
|
surface.ApplyBitmapEffect(new InvertEffect());
|
||||||
updateUndoRedoSurfaceDependencies();
|
updateUndoRedoSurfaceDependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace Greenshot.Helpers {
|
||||||
/// <param name="image">The image to send</param>
|
/// <param name="image">The image to send</param>
|
||||||
/// <param name="captureDetails">ICaptureDetails</param>
|
/// <param name="captureDetails">ICaptureDetails</param>
|
||||||
public static void SendImage(ISurface surface, ICaptureDetails captureDetails) {
|
public static void SendImage(ISurface surface, ICaptureDetails captureDetails) {
|
||||||
string tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new OutputSettings());
|
string tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings());
|
||||||
|
|
||||||
if (tmpFile != null) {
|
if (tmpFile != null) {
|
||||||
// Store the list of currently active windows, so we can make sure we show the email window later!
|
// Store the list of currently active windows, so we can make sure we show the email window later!
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace GreenshotBoxPlugin {
|
||||||
/// This will be called when the menu item in the Editor is clicked
|
/// This will be called when the menu item in the Editor is clicked
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload) {
|
public string Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload) {
|
||||||
OutputSettings outputSettings = new OutputSettings(config.UploadFormat, config.UploadJpegQuality, false);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(config.UploadFormat, config.UploadJpegQuality, false);
|
||||||
try {
|
try {
|
||||||
string url = null;
|
string url = null;
|
||||||
string filename = Path.GetFileName(FilenameHelper.GetFilename(config.UploadFormat, captureDetails));
|
string filename = Path.GetFileName(FilenameHelper.GetFilename(config.UploadFormat, captureDetails));
|
||||||
|
|
|
@ -155,7 +155,7 @@ namespace GreenshotConfluencePlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool upload(ISurface surfaceToUpload, Page page, string filename, out string errorMessage) {
|
private bool upload(ISurface surfaceToUpload, Page page, string filename, out string errorMessage) {
|
||||||
OutputSettings outputSettings = new OutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors);
|
||||||
errorMessage = null;
|
errorMessage = null;
|
||||||
try {
|
try {
|
||||||
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("confluence", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("confluence", LangKey.communication_wait),
|
||||||
|
|
|
@ -113,7 +113,7 @@ namespace GreenshotDropboxPlugin {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl) {
|
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl) {
|
||||||
uploadUrl = null;
|
uploadUrl = null;
|
||||||
OutputSettings outputSettings = new OutputSettings(config.UploadFormat, config.UploadJpegQuality, false);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(config.UploadFormat, config.UploadJpegQuality, false);
|
||||||
try {
|
try {
|
||||||
string dropboxUrl = null;
|
string dropboxUrl = null;
|
||||||
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("dropbox", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("dropbox", LangKey.communication_wait),
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace GreenshotDropboxPlugin {
|
||||||
private DropboxUtils() {
|
private DropboxUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string UploadToDropbox(ISurface surfaceToUpload, OutputSettings outputSettings, string filename) {
|
public static string UploadToDropbox(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string filename) {
|
||||||
OAuthSession oAuth = new OAuthSession(DropBoxCredentials.CONSUMER_KEY, DropBoxCredentials.CONSUMER_SECRET);
|
OAuthSession oAuth = new OAuthSession(DropBoxCredentials.CONSUMER_KEY, DropBoxCredentials.CONSUMER_SECRET);
|
||||||
oAuth.BrowserSize = new Size(1080, 650);
|
oAuth.BrowserSize = new Size(1080, 650);
|
||||||
oAuth.CheckVerifier = false;
|
oAuth.CheckVerifier = false;
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace ExternalCommand {
|
||||||
|
|
||||||
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
|
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
|
||||||
ExportInformation exportInformation = new ExportInformation(this.Designation, this.Description);
|
ExportInformation exportInformation = new ExportInformation(this.Designation, this.Description);
|
||||||
OutputSettings outputSettings = new OutputSettings();
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings();
|
||||||
|
|
||||||
|
|
||||||
if (presetCommand != null) {
|
if (presetCommand != null) {
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace GreenshotFlickrPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Upload(ICaptureDetails captureDetails, ISurface surface, ExportInformation exportInformation) {
|
public void Upload(ICaptureDetails captureDetails, ISurface surface, ExportInformation exportInformation) {
|
||||||
OutputSettings outputSettings = new OutputSettings(config.UploadFormat, config.UploadJpegQuality, false);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(config.UploadFormat, config.UploadJpegQuality, false);
|
||||||
try {
|
try {
|
||||||
string flickrUrl = null;
|
string flickrUrl = null;
|
||||||
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("flickr", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("flickr", LangKey.communication_wait),
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace GreenshotFlickrPlugin {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="imageData">byte[] with image data</param>
|
/// <param name="imageData">byte[] with image data</param>
|
||||||
/// <returns>url to image</returns>
|
/// <returns>url to image</returns>
|
||||||
public static string UploadToFlickr(ISurface surfaceToUpload, OutputSettings outputSettings, string title, string filename) {
|
public static string UploadToFlickr(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename) {
|
||||||
OAuthSession oAuth = new OAuthSession(FlickrCredentials.ConsumerKey, FlickrCredentials.ConsumerSecret);
|
OAuthSession oAuth = new OAuthSession(FlickrCredentials.ConsumerKey, FlickrCredentials.ConsumerSecret);
|
||||||
oAuth.BrowserSize = new Size(520, 800);
|
oAuth.BrowserSize = new Size(520, 800);
|
||||||
oAuth.CheckVerifier = false;
|
oAuth.CheckVerifier = false;
|
||||||
|
|
|
@ -152,7 +152,7 @@ namespace GreenshotImgurPlugin {
|
||||||
/// <param name="uploadURL">out string for the url</param>
|
/// <param name="uploadURL">out string for the url</param>
|
||||||
/// <returns>true if the upload succeeded</returns>
|
/// <returns>true if the upload succeeded</returns>
|
||||||
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadURL) {
|
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadURL) {
|
||||||
OutputSettings outputSettings = new OutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors);
|
||||||
try {
|
try {
|
||||||
string filename = Path.GetFileName(FilenameHelper.GetFilename(config.UploadFormat, captureDetails));
|
string filename = Path.GetFileName(FilenameHelper.GetFilename(config.UploadFormat, captureDetails));
|
||||||
ImgurInfo imgurInfo = null;
|
ImgurInfo imgurInfo = null;
|
||||||
|
|
|
@ -99,7 +99,7 @@ namespace GreenshotImgurPlugin {
|
||||||
/// <param name="title">Title</param>
|
/// <param name="title">Title</param>
|
||||||
/// <param name="filename">Filename</param>
|
/// <param name="filename">Filename</param>
|
||||||
/// <returns>ImgurInfo with details</returns>
|
/// <returns>ImgurInfo with details</returns>
|
||||||
public static ImgurInfo UploadToImgur(ISurface surfaceToUpload, OutputSettings outputSettings, string title, string filename) {
|
public static ImgurInfo UploadToImgur(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename) {
|
||||||
IDictionary<string, object> uploadParameters = new Dictionary<string, object>();
|
IDictionary<string, object> uploadParameters = new Dictionary<string, object>();
|
||||||
IDictionary<string, object> otherParameters = new Dictionary<string, object>();
|
IDictionary<string, object> otherParameters = new Dictionary<string, object>();
|
||||||
// add title
|
// add title
|
||||||
|
|
|
@ -26,7 +26,7 @@ using Greenshot.IniFile;
|
||||||
using GreenshotJiraPlugin;
|
using GreenshotJiraPlugin;
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
//using GreenshotJiraPlugin.JiraSoap;
|
using GreenshotJiraPlugin.JiraSoap;
|
||||||
|
|
||||||
namespace Jira {
|
namespace Jira {
|
||||||
#region transport classes
|
#region transport classes
|
||||||
|
|
|
@ -102,7 +102,7 @@ namespace GreenshotJiraPlugin {
|
||||||
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surfaceToUpload, ICaptureDetails captureDetails) {
|
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surfaceToUpload, ICaptureDetails captureDetails) {
|
||||||
ExportInformation exportInformation = new ExportInformation(this.Designation, this.Description);
|
ExportInformation exportInformation = new ExportInformation(this.Designation, this.Description);
|
||||||
string filename = Path.GetFileName(FilenameHelper.GetFilename(config.UploadFormat, captureDetails));
|
string filename = Path.GetFileName(FilenameHelper.GetFilename(config.UploadFormat, captureDetails));
|
||||||
OutputSettings outputSettings = new OutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors);
|
||||||
if (jira != null) {
|
if (jira != null) {
|
||||||
try {
|
try {
|
||||||
// Run upload in the background
|
// Run upload in the background
|
||||||
|
|
|
@ -27,6 +27,7 @@ using System.Windows.Forms;
|
||||||
using Greenshot.IniFile;
|
using Greenshot.IniFile;
|
||||||
using Greenshot.Plugin;
|
using Greenshot.Plugin;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
|
using Greenshot.Core;
|
||||||
|
|
||||||
//using Microsoft.Win32;
|
//using Microsoft.Win32;
|
||||||
|
|
||||||
|
@ -137,9 +138,18 @@ namespace GreenshotOCR {
|
||||||
private const int MIN_HEIGHT = 130;
|
private const int MIN_HEIGHT = 130;
|
||||||
public string DoOCR(ISurface surface) {
|
public string DoOCR(ISurface surface) {
|
||||||
string filePath = null;
|
string filePath = null;
|
||||||
OutputSettings outputSettings = new OutputSettings(OutputFormat.bmp, 0, true);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(OutputFormat.bmp, 0, true);
|
||||||
// TODO: Add some filter & output settings so the output image is easier to process for the MODI-OCR code
|
outputSettings.ReduceColors = true;
|
||||||
|
// We only want the background
|
||||||
|
outputSettings.SaveBackgroundOnly = true;
|
||||||
|
// Force Grayscale output
|
||||||
|
outputSettings.Effects.Add(new GrayscaleEffect());
|
||||||
|
|
||||||
// Also we need to check the size, resize if needed to 130x130 this is the minimum
|
// Also we need to check the size, resize if needed to 130x130 this is the minimum
|
||||||
|
if (surface.Image.Width < MIN_WIDTH || surface.Image.Height < MIN_HEIGHT) {
|
||||||
|
IEffect resizeEffect = new ResizeEffect(Math.Max(surface.Image.Width, MIN_WIDTH), Math.Max(surface.Image.Height, MIN_HEIGHT), true);
|
||||||
|
outputSettings.Effects.Add(resizeEffect);
|
||||||
|
}
|
||||||
filePath = ImageOutput.SaveToTmpFile(surface, outputSettings, null);
|
filePath = ImageOutput.SaveToTmpFile(surface, outputSettings, null);
|
||||||
|
|
||||||
LOG.Debug("Saved tmp file to: " + filePath);
|
LOG.Debug("Saved tmp file to: " + filePath);
|
||||||
|
@ -163,11 +173,12 @@ namespace GreenshotOCR {
|
||||||
File.Delete(filePath);
|
File.Delete(filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text == null || text.Trim().Length == 0) {
|
if (text == null || text.Trim().Length == 0) {
|
||||||
LOG.Info("No text returned");
|
LOG.Info("No text returned");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LOG.DebugFormat("Pasting OCR Text to Clipboard: {0}", text);
|
LOG.DebugFormat("Pasting OCR Text to Clipboard: {0}", text);
|
||||||
// Paste to Clipboard (the Plugin currently doesn't have access to the ClipboardHelper from Greenshot
|
// Paste to Clipboard (the Plugin currently doesn't have access to the ClipboardHelper from Greenshot
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace GreenshotOfficePlugin {
|
||||||
ExportInformation exportInformation = new ExportInformation(this.Designation, this.Description);
|
ExportInformation exportInformation = new ExportInformation(this.Designation, this.Description);
|
||||||
string tmpFile = captureDetails.Filename;
|
string tmpFile = captureDetails.Filename;
|
||||||
if (tmpFile == null || surface.Modified) {
|
if (tmpFile == null || surface.Modified) {
|
||||||
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new OutputSettings(OutputFormat.png));
|
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings(OutputFormat.png));
|
||||||
}
|
}
|
||||||
if (workbookName != null) {
|
if (workbookName != null) {
|
||||||
ExcelExporter.InsertIntoExistingWorkbook(workbookName, tmpFile);
|
ExcelExporter.InsertIntoExistingWorkbook(workbookName, tmpFile);
|
||||||
|
|
|
@ -153,7 +153,7 @@ namespace GreenshotOfficePlugin {
|
||||||
// Outlook logic
|
// Outlook logic
|
||||||
string tmpFile = captureDetails.Filename;
|
string tmpFile = captureDetails.Filename;
|
||||||
if (tmpFile == null || surface.Modified) {
|
if (tmpFile == null || surface.Modified) {
|
||||||
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new OutputSettings());
|
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings());
|
||||||
} else {
|
} else {
|
||||||
LOG.InfoFormat("Using already available file: {0}", tmpFile);
|
LOG.InfoFormat("Using already available file: {0}", tmpFile);
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ namespace GreenshotOfficePlugin {
|
||||||
string tmpFile = captureDetails.Filename;
|
string tmpFile = captureDetails.Filename;
|
||||||
Size imageSize = Size.Empty;
|
Size imageSize = Size.Empty;
|
||||||
if (tmpFile == null || surface.Modified) {
|
if (tmpFile == null || surface.Modified) {
|
||||||
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new OutputSettings());
|
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings());
|
||||||
imageSize = surface.Image.Size;
|
imageSize = surface.Image.Size;
|
||||||
}
|
}
|
||||||
if (presentationName != null) {
|
if (presentationName != null) {
|
||||||
|
|
|
@ -112,7 +112,7 @@ namespace GreenshotOfficePlugin {
|
||||||
ExportInformation exportInformation = new ExportInformation(this.Designation, this.Description);
|
ExportInformation exportInformation = new ExportInformation(this.Designation, this.Description);
|
||||||
string tmpFile = captureDetails.Filename;
|
string tmpFile = captureDetails.Filename;
|
||||||
if (tmpFile == null || surface.Modified) {
|
if (tmpFile == null || surface.Modified) {
|
||||||
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new OutputSettings(OutputFormat.png));
|
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings(OutputFormat.png));
|
||||||
}
|
}
|
||||||
if (documentCaption != null) {
|
if (documentCaption != null) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace Greenshot.Interop.Office {
|
||||||
|
|
||||||
public static void ExportToPage(ISurface surfaceToUpload, OneNotePage page) {
|
public static void ExportToPage(ISurface surfaceToUpload, OneNotePage page) {
|
||||||
using (MemoryStream pngStream = new MemoryStream()) {
|
using (MemoryStream pngStream = new MemoryStream()) {
|
||||||
OutputSettings pngOutputSettings = new OutputSettings(OutputFormat.png, 100, false);
|
SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false);
|
||||||
ImageOutput.SaveToStream(surfaceToUpload, pngStream, pngOutputSettings);
|
ImageOutput.SaveToStream(surfaceToUpload, pngStream, pngOutputSettings);
|
||||||
string base64String = Convert.ToBase64String(pngStream.GetBuffer());
|
string base64String = Convert.ToBase64String(pngStream.GetBuffer());
|
||||||
string imageXmlStr = string.Format(XML_IMAGE_CONTENT, base64String, surfaceToUpload.Image.Width, surfaceToUpload.Image.Height);
|
string imageXmlStr = string.Format(XML_IMAGE_CONTENT, base64String, surfaceToUpload.Image.Width, surfaceToUpload.Image.Height);
|
||||||
|
|
|
@ -115,7 +115,7 @@ namespace GreenshotPhotobucketPlugin {
|
||||||
/// <param name="uploadURL">out string for the url</param>
|
/// <param name="uploadURL">out string for the url</param>
|
||||||
/// <returns>true if the upload succeeded</returns>
|
/// <returns>true if the upload succeeded</returns>
|
||||||
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadURL) {
|
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadURL) {
|
||||||
OutputSettings outputSettings = new OutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors);
|
||||||
try {
|
try {
|
||||||
string filename = Path.GetFileName(FilenameHelper.GetFilename(config.UploadFormat, captureDetails));
|
string filename = Path.GetFileName(FilenameHelper.GetFilename(config.UploadFormat, captureDetails));
|
||||||
PhotobucketInfo photobucketInfo = null;
|
PhotobucketInfo photobucketInfo = null;
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace GreenshotPhotobucketPlugin {
|
||||||
/// For more details on the available parameters, see: http://api.Photobucket.com/resources_anon
|
/// For more details on the available parameters, see: http://api.Photobucket.com/resources_anon
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>PhotobucketResponse</returns>
|
/// <returns>PhotobucketResponse</returns>
|
||||||
public static PhotobucketInfo UploadToPhotobucket(ISurface surfaceToUpload, OutputSettings outputSettings, string title, string filename) {
|
public static PhotobucketInfo UploadToPhotobucket(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename) {
|
||||||
string responseString;
|
string responseString;
|
||||||
|
|
||||||
OAuthSession oAuth = new OAuthSession(PhotobucketCredentials.ConsumerKey, PhotobucketCredentials.ConsumerSecret);
|
OAuthSession oAuth = new OAuthSession(PhotobucketCredentials.ConsumerKey, PhotobucketCredentials.ConsumerSecret);
|
||||||
|
|
|
@ -110,7 +110,7 @@ namespace GreenshotPicasaPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl) {
|
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl) {
|
||||||
OutputSettings outputSettings = new OutputSettings(config.UploadFormat, config.UploadJpegQuality);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(config.UploadFormat, config.UploadJpegQuality);
|
||||||
try {
|
try {
|
||||||
string url = null;
|
string url = null;
|
||||||
new PleaseWaitForm().ShowAndWait(PicasaPlugin.Attributes.Name, Language.GetString("picasa", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait(PicasaPlugin.Attributes.Name, Language.GetString("picasa", LangKey.communication_wait),
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace GreenshotPicasaPlugin {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="imageData">byte[] with image data</param>
|
/// <param name="imageData">byte[] with image data</param>
|
||||||
/// <returns>PicasaResponse</returns>
|
/// <returns>PicasaResponse</returns>
|
||||||
public static string UploadToPicasa(ISurface surfaceToUpload, OutputSettings outputSettings, string title, string filename) {
|
public static string UploadToPicasa(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename) {
|
||||||
OAuthSession oAuth = new OAuthSession(PicasaCredentials.ConsumerKey, PicasaCredentials.ConsumerSecret);
|
OAuthSession oAuth = new OAuthSession(PicasaCredentials.ConsumerKey, PicasaCredentials.ConsumerSecret);
|
||||||
oAuth.BrowserSize = new Size(1020, 590);
|
oAuth.BrowserSize = new Size(1020, 590);
|
||||||
oAuth.AccessTokenUrl = "https://www.google.com/accounts/OAuthGetAccessToken";
|
oAuth.AccessTokenUrl = "https://www.google.com/accounts/OAuthGetAccessToken";
|
||||||
|
|
|
@ -30,12 +30,12 @@ namespace GreenshotPlugin.Controls {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class QualityDialog : GreenshotForm {
|
public partial class QualityDialog : GreenshotForm {
|
||||||
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
|
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
|
||||||
public OutputSettings Settings {
|
public SurfaceOutputSettings Settings {
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QualityDialog(OutputSettings outputSettings) {
|
public QualityDialog(SurfaceOutputSettings outputSettings) {
|
||||||
Settings = outputSettings;
|
Settings = outputSettings;
|
||||||
//
|
//
|
||||||
// The InitializeComponent() call is required for Windows Forms designer support.
|
// The InitializeComponent() call is required for Windows Forms designer support.
|
||||||
|
|
|
@ -388,7 +388,7 @@ EndSelection:<<<<<<<4
|
||||||
if (config.ClipboardFormats.Contains(ClipboardFormat.PNG) || config.ClipboardFormats.Contains(ClipboardFormat.HTMLDATAURL)) {
|
if (config.ClipboardFormats.Contains(ClipboardFormat.PNG) || config.ClipboardFormats.Contains(ClipboardFormat.HTMLDATAURL)) {
|
||||||
pngStream = new MemoryStream();
|
pngStream = new MemoryStream();
|
||||||
// PNG works for Powerpoint
|
// 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);
|
ImageOutput.SaveToStream(surface, pngStream, pngOutputSettings);
|
||||||
pngStream.Seek(0, SeekOrigin.Begin);
|
pngStream.Seek(0, SeekOrigin.Begin);
|
||||||
}
|
}
|
||||||
|
@ -401,7 +401,7 @@ EndSelection:<<<<<<<4
|
||||||
if (config.ClipboardFormats.Contains(ClipboardFormat.DIB)) {
|
if (config.ClipboardFormats.Contains(ClipboardFormat.DIB)) {
|
||||||
bmpStream = new MemoryStream();
|
bmpStream = new MemoryStream();
|
||||||
// Save image as BMP
|
// 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);
|
ImageOutput.SaveToStream(surface, bmpStream, bmpOutputSettings);
|
||||||
|
|
||||||
imageStream = new MemoryStream();
|
imageStream = new MemoryStream();
|
||||||
|
@ -414,7 +414,7 @@ EndSelection:<<<<<<<4
|
||||||
|
|
||||||
// Set the HTML
|
// Set the HTML
|
||||||
if (config.ClipboardFormats.Contains(ClipboardFormat.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);
|
string html = getHTMLString(surface, tmpFile);
|
||||||
ido.SetText(html, TextDataFormat.Html);
|
ido.SetText(html, TextDataFormat.Html);
|
||||||
} else if (config.ClipboardFormats.Contains(ClipboardFormat.HTMLDATAURL)) {
|
} else if (config.ClipboardFormats.Contains(ClipboardFormat.HTMLDATAURL)) {
|
||||||
|
|
|
@ -27,6 +27,8 @@ using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Greenshot.IniFile;
|
using Greenshot.IniFile;
|
||||||
using GreenshotPlugin.UnmanagedHelpers;
|
using GreenshotPlugin.UnmanagedHelpers;
|
||||||
|
using Greenshot.Plugin;
|
||||||
|
using Greenshot.Core;
|
||||||
|
|
||||||
namespace GreenshotPlugin.Core {
|
namespace GreenshotPlugin.Core {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -36,9 +38,26 @@ namespace GreenshotPlugin.Core {
|
||||||
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ImageHelper));
|
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ImageHelper));
|
||||||
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
|
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) {
|
public static Image CreateThumbnail(Image image, int thumbWidth, int thumbHeight) {
|
||||||
return CreateThumbnail(image, thumbWidth, thumbHeight, -1, -1);
|
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) {
|
public static Image CreateThumbnail(Image image, int thumbWidth, int thumbHeight, int maxWidth, int maxHeight) {
|
||||||
int srcWidth=image.Width;
|
int srcWidth=image.Width;
|
||||||
int srcHeight=image.Height;
|
int srcHeight=image.Height;
|
||||||
|
@ -90,11 +109,11 @@ namespace GreenshotPlugin.Core {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper method for the FindAutoCropRectangle
|
/// Private helper method for the FindAutoCropRectangle
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="buffer"></param>
|
/// <param name="buffer"></param>
|
||||||
/// <param name="colorPoint"></param>
|
/// <param name="colorPoint"></param>
|
||||||
/// <returns></returns>
|
/// <returns>Rectangle</returns>
|
||||||
private static Rectangle FindAutoCropRectangle(BitmapBuffer buffer, Point colorPoint, int cropDifference) {
|
private static Rectangle FindAutoCropRectangle(BitmapBuffer buffer, Point colorPoint, int cropDifference) {
|
||||||
Rectangle cropRectangle = Rectangle.Empty;
|
Rectangle cropRectangle = Rectangle.Empty;
|
||||||
Color referenceColor = buffer.GetColorAtWithoutAlpha(colorPoint.X,colorPoint.Y);
|
Color referenceColor = buffer.GetColorAtWithoutAlpha(colorPoint.X,colorPoint.Y);
|
||||||
|
@ -225,19 +244,15 @@ namespace GreenshotPlugin.Core {
|
||||||
}
|
}
|
||||||
return fileBitmap;
|
return fileBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if we support the supplied PixelFormat
|
/// <summary>
|
||||||
*/
|
/// Based on: http://www.codeproject.com/KB/cs/IconExtractor.aspx
|
||||||
private static bool isSupported(PixelFormat pixelformat) {
|
/// And a hint from: http://www.codeproject.com/KB/cs/IconLib.aspx
|
||||||
return (PixelFormat.Format32bppArgb.Equals(pixelformat)||
|
/// </summary>
|
||||||
PixelFormat.Format32bppRgb.Equals(pixelformat) ||
|
/// <param name="iconStream">Stream with the icon information</param>
|
||||||
PixelFormat.Format24bppRgb.Equals(pixelformat));
|
/// <returns>Bitmap with the Vista Icon (256x256)</returns>
|
||||||
}
|
private static Bitmap ExtractVistaIcon(Stream iconStream) {
|
||||||
|
|
||||||
// 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) {
|
|
||||||
const int SizeICONDIR = 6;
|
const int SizeICONDIR = 6;
|
||||||
const int SizeICONDIRENTRY = 16;
|
const int SizeICONDIRENTRY = 16;
|
||||||
Bitmap bmpPngExtracted = null;
|
Bitmap bmpPngExtracted = null;
|
||||||
|
@ -315,6 +330,44 @@ namespace GreenshotPlugin.Core {
|
||||||
return Shell32.ExtractIconEx(location, -1, out large, out small, 0);
|
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>
|
/// <summary>
|
||||||
/// Make the picture look like it's torn
|
/// Make the picture look like it's torn
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -843,9 +896,10 @@ namespace GreenshotPlugin.Core {
|
||||||
/// <param name="targetPixelformat">What pixel format must the returning bitmap have</param>
|
/// <param name="targetPixelformat">What pixel format must the returning bitmap have</param>
|
||||||
/// <param name="offset">How many pixels is the original image moved?</param>
|
/// <param name="offset">How many pixels is the original image moved?</param>
|
||||||
/// <returns>Bitmap with the shadow, is bigger than the sourceBitmap!!</returns>
|
/// <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
|
// Create a new "clean" image
|
||||||
Bitmap returnImage = null;
|
Bitmap returnImage = null;
|
||||||
|
offset = shadowOffset;
|
||||||
offset.X += shadowSize - 1;
|
offset.X += shadowSize - 1;
|
||||||
offset.Y += 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)) {
|
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>
|
/// <returns>Bitmap with grayscale</returns>
|
||||||
public static Bitmap CreateGrayscale(Bitmap sourceBitmap) {
|
public static Bitmap CreateGrayscale(Bitmap sourceBitmap) {
|
||||||
//create a blank bitmap the same size as original
|
//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)) {
|
using (Graphics graphics = Graphics.FromImage(newBitmap)) {
|
||||||
// create the grayscale ColorMatrix
|
// create the grayscale ColorMatrix
|
||||||
ColorMatrix colorMatrix = new ColorMatrix(
|
ColorMatrix colorMatrix = new ColorMatrix(
|
||||||
|
|
|
@ -28,6 +28,7 @@ using System.Windows.Forms;
|
||||||
using Greenshot.IniFile;
|
using Greenshot.IniFile;
|
||||||
using Greenshot.Plugin;
|
using Greenshot.Plugin;
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
|
using Greenshot.Core;
|
||||||
|
|
||||||
namespace GreenshotPlugin.Core {
|
namespace GreenshotPlugin.Core {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -74,7 +75,7 @@ namespace GreenshotPlugin.Core {
|
||||||
/// 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, OutputSettings outputSettings) {
|
public static void SaveToStream(ISurface surface, Stream stream, SurfaceOutputSettings outputSettings) {
|
||||||
ImageFormat imageFormat = null;
|
ImageFormat imageFormat = null;
|
||||||
bool disposeImage = false;
|
bool disposeImage = false;
|
||||||
bool useMemoryStream = false;
|
bool useMemoryStream = false;
|
||||||
|
@ -112,7 +113,7 @@ namespace GreenshotPlugin.Core {
|
||||||
|
|
||||||
// check what image we want to save
|
// check what image we want to save
|
||||||
Image imageToSave = null;
|
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
|
// We save the image of the surface, this should not be disposed
|
||||||
imageToSave = surface.Image;
|
imageToSave = surface.Image;
|
||||||
} else {
|
} else {
|
||||||
|
@ -122,7 +123,18 @@ namespace GreenshotPlugin.Core {
|
||||||
}
|
}
|
||||||
try {
|
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)) {
|
if (imageFormat != ImageFormat.Png && Image.IsAlphaPixelFormat(imageToSave.PixelFormat)) {
|
||||||
Image nonAlphaImage = ImageHelper.Clone(imageToSave, PixelFormat.Format24bppRgb);
|
Image nonAlphaImage = ImageHelper.Clone(imageToSave, PixelFormat.Format24bppRgb);
|
||||||
if (disposeImage) {
|
if (disposeImage) {
|
||||||
|
@ -141,7 +153,7 @@ namespace GreenshotPlugin.Core {
|
||||||
if (outputSettings.ReduceColors || colorCount < 256) {
|
if (outputSettings.ReduceColors || colorCount < 256) {
|
||||||
try {
|
try {
|
||||||
LOG.Info("Reducing colors on bitmap to 255.");
|
LOG.Info("Reducing colors on bitmap to 255.");
|
||||||
Image tmpImage = quantizer.GetQuantizedImage(255);
|
tmpImage = quantizer.GetQuantizedImage(255);
|
||||||
if (disposeImage) {
|
if (disposeImage) {
|
||||||
imageToSave.Dispose();
|
imageToSave.Dispose();
|
||||||
}
|
}
|
||||||
|
@ -152,8 +164,6 @@ namespace GreenshotPlugin.Core {
|
||||||
LOG.Warn("Error occurred while Quantizing the image, ignoring and using original. Error: ", e);
|
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
|
// Create meta-data
|
||||||
|
@ -273,7 +283,7 @@ namespace GreenshotPlugin.Core {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves image to specific path with specified quality
|
/// Saves image to specific path with specified quality
|
||||||
/// </summary>
|
/// </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);
|
fullPath = FilenameHelper.MakeFQFilenameSafe(fullPath);
|
||||||
string path = Path.GetDirectoryName(fullPath);
|
string path = Path.GetDirectoryName(fullPath);
|
||||||
|
|
||||||
|
@ -334,7 +344,7 @@ namespace GreenshotPlugin.Core {
|
||||||
if (dialogResult.Equals(DialogResult.OK)) {
|
if (dialogResult.Equals(DialogResult.OK)) {
|
||||||
try {
|
try {
|
||||||
string fileNameWithExtension = saveImageFileDialog.FileNameWithExtension;
|
string fileNameWithExtension = saveImageFileDialog.FileNameWithExtension;
|
||||||
OutputSettings outputSettings = new OutputSettings(FormatForFilename(fileNameWithExtension));
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(FormatForFilename(fileNameWithExtension));
|
||||||
if (conf.OutputFilePromptQuality) {
|
if (conf.OutputFilePromptQuality) {
|
||||||
QualityDialog qualityDialog = new QualityDialog(outputSettings);
|
QualityDialog qualityDialog = new QualityDialog(outputSettings);
|
||||||
qualityDialog.ShowDialog();
|
qualityDialog.ShowDialog();
|
||||||
|
@ -360,7 +370,7 @@ namespace GreenshotPlugin.Core {
|
||||||
/// <param name="captureDetails"></param>
|
/// <param name="captureDetails"></param>
|
||||||
/// <param name="outputSettings"></param>
|
/// <param name="outputSettings"></param>
|
||||||
/// <returns>Path to image file</returns>
|
/// <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;
|
string pattern = conf.OutputFileFilenamePattern;
|
||||||
if (pattern == null || string.IsNullOrEmpty(pattern.Trim())) {
|
if (pattern == null || string.IsNullOrEmpty(pattern.Trim())) {
|
||||||
pattern = "greenshot ${capturetime}";
|
pattern = "greenshot ${capturetime}";
|
||||||
|
@ -393,7 +403,7 @@ namespace GreenshotPlugin.Core {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="image"></param>
|
/// <param name="image"></param>
|
||||||
/// <returns></returns>
|
/// <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();
|
string tmpFile = Path.GetRandomFileName() + "." + outputSettings.Format.ToString();
|
||||||
// Prevent problems with "other characters", which could cause problems
|
// Prevent problems with "other characters", which could cause problems
|
||||||
tmpFile = Regex.Replace(tmpFile, @"[^\d\w\.]", "");
|
tmpFile = Regex.Replace(tmpFile, @"[^\d\w\.]", "");
|
||||||
|
|
|
@ -415,10 +415,10 @@ namespace GreenshotPlugin.Core {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SurfaceContainer : IBinaryContainer {
|
public class SurfaceContainer : IBinaryContainer {
|
||||||
private ISurface surface;
|
private ISurface surface;
|
||||||
private OutputSettings outputSettings;
|
private SurfaceOutputSettings outputSettings;
|
||||||
private string fileName;
|
private string fileName;
|
||||||
|
|
||||||
public SurfaceContainer(ISurface surface, OutputSettings outputSettings, string filename) {
|
public SurfaceContainer(ISurface surface, SurfaceOutputSettings outputSettings, string filename) {
|
||||||
this.surface = surface;
|
this.surface = surface;
|
||||||
this.outputSettings = outputSettings;
|
this.outputSettings = outputSettings;
|
||||||
this.fileName = filename;
|
this.fileName = filename;
|
||||||
|
|
|
@ -26,6 +26,7 @@ using System.Windows.Forms;
|
||||||
using Greenshot.Plugin.Drawing;
|
using Greenshot.Plugin.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Greenshot.Core;
|
||||||
|
|
||||||
namespace Greenshot.Plugin {
|
namespace Greenshot.Plugin {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -33,7 +34,6 @@ namespace Greenshot.Plugin {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
//public enum HorizontalAlignment {LEFT, CENTER, RIGHT};
|
//public enum HorizontalAlignment {LEFT, CENTER, RIGHT};
|
||||||
public enum VerticalAlignment {TOP, CENTER, BOTTOM};
|
public enum VerticalAlignment {TOP, CENTER, BOTTOM};
|
||||||
public enum Effects { Shadow, TornEdge, Border, Grayscale, RotateClockwise, RotateCounterClockwise, Invert };
|
|
||||||
|
|
||||||
public enum SurfaceMessageTyp {
|
public enum SurfaceMessageTyp {
|
||||||
FileSaved,
|
FileSaved,
|
||||||
|
@ -148,7 +148,7 @@ namespace Greenshot.Plugin {
|
||||||
}
|
}
|
||||||
void RemoveElement(IDrawableContainer elementToRemove, bool makeUndoable);
|
void RemoveElement(IDrawableContainer elementToRemove, bool makeUndoable);
|
||||||
void SendMessageEvent(object source, SurfaceMessageTyp messageType, string message);
|
void SendMessageEvent(object source, SurfaceMessageTyp messageType, string message);
|
||||||
void ApplyBitmapEffect(Effects effect);
|
void ApplyBitmapEffect(IEffect effect);
|
||||||
void RemoveCursor();
|
void RemoveCursor();
|
||||||
bool HasCursor {
|
bool HasCursor {
|
||||||
get;
|
get;
|
||||||
|
|
|
@ -26,6 +26,7 @@ using System.Windows.Forms;
|
||||||
|
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using Greenshot.IniFile;
|
using Greenshot.IniFile;
|
||||||
|
using Greenshot.Core;
|
||||||
|
|
||||||
namespace Greenshot.Plugin {
|
namespace Greenshot.Plugin {
|
||||||
[Serializable]
|
[Serializable]
|
||||||
|
@ -74,25 +75,26 @@ namespace Greenshot.Plugin {
|
||||||
// Delegates for hooking up events.
|
// Delegates for hooking up events.
|
||||||
public delegate void HotKeyHandler();
|
public delegate void HotKeyHandler();
|
||||||
|
|
||||||
public class OutputSettings {
|
public class SurfaceOutputSettings {
|
||||||
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
|
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
|
||||||
private bool reduceColors;
|
private bool reduceColors;
|
||||||
|
private List<IEffect> effects = new List<IEffect>();
|
||||||
|
|
||||||
public OutputSettings() {
|
public SurfaceOutputSettings() {
|
||||||
Format = conf.OutputFileFormat;
|
Format = conf.OutputFileFormat;
|
||||||
JPGQuality = conf.OutputFileJpegQuality;
|
JPGQuality = conf.OutputFileJpegQuality;
|
||||||
ReduceColors = conf.OutputFileReduceColors;
|
ReduceColors = conf.OutputFileReduceColors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputSettings(OutputFormat format) : this() {
|
public SurfaceOutputSettings(OutputFormat format) : this() {
|
||||||
Format = format;
|
Format = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputSettings(OutputFormat format, int quality) : this(format) {
|
public SurfaceOutputSettings(OutputFormat format, int quality) : this(format) {
|
||||||
JPGQuality = quality;
|
JPGQuality = quality;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputSettings(OutputFormat format, int quality, bool reduceColors) : this(format, quality) {
|
public SurfaceOutputSettings(OutputFormat format, int quality, bool reduceColors) : this(format, quality) {
|
||||||
ReduceColors = reduceColors;
|
ReduceColors = reduceColors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +108,17 @@ namespace Greenshot.Plugin {
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SaveBackgroundOnly {
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IEffect> Effects {
|
||||||
|
get {
|
||||||
|
return effects;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool ReduceColors {
|
public bool ReduceColors {
|
||||||
get {
|
get {
|
||||||
// Fix for Bug #3468436, force quantizing when output format is gif as this has only 256 colors!
|
// Fix for Bug #3468436, force quantizing when output format is gif as this has only 256 colors!
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue