mirror of
https://github.com/greenshot/greenshot
synced 2025-07-16 10:03:44 -07:00
Fixed and optimized some drawing routines, still didn't find a solution for shadowing when target format has transparency.
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@1648 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
46758d238c
commit
dede5cf292
16 changed files with 275 additions and 161 deletions
|
@ -44,12 +44,15 @@ namespace Greenshot.Drawing {
|
||||||
AddField(GetType(), FieldType.ARROWHEADS, Greenshot.Drawing.ArrowContainer.ArrowHeadCombination.END_POINT);
|
AddField(GetType(), FieldType.ARROWHEADS, Greenshot.Drawing.ArrowContainer.ArrowHeadCombination.END_POINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(Graphics g, RenderMode rm) {
|
public override void Draw(Graphics graphics, RenderMode rm) {
|
||||||
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
|
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
|
||||||
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
||||||
|
|
||||||
if (lineThickness > 0 ) {
|
if (lineThickness > 0 ) {
|
||||||
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
|
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
|
||||||
ArrowHeadCombination heads = (ArrowHeadCombination)GetFieldValue(FieldType.ARROWHEADS);
|
ArrowHeadCombination heads = (ArrowHeadCombination)GetFieldValue(FieldType.ARROWHEADS);
|
||||||
if (shadow) {
|
if (shadow) {
|
||||||
|
@ -63,7 +66,7 @@ namespace Greenshot.Drawing {
|
||||||
shadowCapPen.Width = lineThickness;
|
shadowCapPen.Width = lineThickness;
|
||||||
SetArrowHeads(heads, shadowCapPen);
|
SetArrowHeads(heads, shadowCapPen);
|
||||||
|
|
||||||
g.DrawLine(shadowCapPen,
|
graphics.DrawLine(shadowCapPen,
|
||||||
this.Left + currentStep,
|
this.Left + currentStep,
|
||||||
this.Top + currentStep,
|
this.Top + currentStep,
|
||||||
this.Left + currentStep + this.Width,
|
this.Left + currentStep + this.Width,
|
||||||
|
@ -80,7 +83,7 @@ namespace Greenshot.Drawing {
|
||||||
|
|
||||||
if ( pen.Width > 0 ) {
|
if ( pen.Width > 0 ) {
|
||||||
SetArrowHeads(heads, pen);
|
SetArrowHeads(heads, pen);
|
||||||
g.DrawLine(pen, this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
|
graphics.DrawLine(pen, this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ using Greenshot.Drawing.Fields;
|
||||||
using Greenshot.Helpers;
|
using Greenshot.Helpers;
|
||||||
using Greenshot.Plugin.Drawing;
|
using Greenshot.Plugin.Drawing;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
|
||||||
namespace Greenshot.Drawing {
|
namespace Greenshot.Drawing {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -54,7 +55,7 @@ namespace Greenshot.Drawing {
|
||||||
if (bitmap != null) {
|
if (bitmap != null) {
|
||||||
bitmap.Dispose();
|
bitmap.Dispose();
|
||||||
}
|
}
|
||||||
bitmap = (Bitmap)value.Clone();
|
bitmap = ImageHelper.Clone(value);
|
||||||
Width = value.Width;
|
Width = value.Width;
|
||||||
Height = value.Height;
|
Height = value.Height;
|
||||||
}
|
}
|
||||||
|
@ -103,6 +104,11 @@ namespace Greenshot.Drawing {
|
||||||
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);
|
||||||
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
|
||||||
if (shadow) {
|
if (shadow) {
|
||||||
ImageAttributes ia = new ImageAttributes();
|
ImageAttributes ia = new ImageAttributes();
|
||||||
ColorMatrix cm = new ColorMatrix();
|
ColorMatrix cm = new ColorMatrix();
|
||||||
|
@ -111,7 +117,7 @@ namespace Greenshot.Drawing {
|
||||||
cm.Matrix22 = 0;
|
cm.Matrix22 = 0;
|
||||||
cm.Matrix33 = 0.25f;
|
cm.Matrix33 = 0.25f;
|
||||||
ia.SetColorMatrix(cm);
|
ia.SetColorMatrix(cm);
|
||||||
graphics.DrawImage(bitmap, new Rectangle(Bounds.Left+2, Bounds.Top+2, Bounds.Width, Bounds.Height), 0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, ia);
|
graphics.DrawImage(bitmap, new Rectangle(Bounds.Left + 2, Bounds.Top + 2, Bounds.Width, Bounds.Height), 0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, ia);
|
||||||
}
|
}
|
||||||
graphics.DrawImage(bitmap, Bounds);
|
graphics.DrawImage(bitmap, Bounds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
using Greenshot.Plugin.Drawing;
|
using Greenshot.Plugin.Drawing;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
|
||||||
namespace Greenshot.Drawing {
|
namespace Greenshot.Drawing {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -98,6 +99,10 @@ namespace Greenshot.Drawing {
|
||||||
|
|
||||||
public override void Draw(Graphics graphics, RenderMode rm) {
|
public override void Draw(Graphics graphics, RenderMode rm) {
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.Default;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.None;
|
||||||
cursor.DrawStretched(graphics, Bounds);
|
cursor.DrawStretched(graphics, Bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -408,7 +408,7 @@ namespace Greenshot.Drawing {
|
||||||
|
|
||||||
public virtual void DrawContent(Graphics graphics, Bitmap bmp, RenderMode renderMode, Rectangle clipRectangle) {
|
public virtual void DrawContent(Graphics graphics, Bitmap bmp, RenderMode renderMode, Rectangle clipRectangle) {
|
||||||
if (Children.Count > 0) {
|
if (Children.Count > 0) {
|
||||||
if(Status != EditStatus.IDLE) {
|
if (Status != EditStatus.IDLE) {
|
||||||
DrawSelectionBorder(graphics, Bounds);
|
DrawSelectionBorder(graphics, Bounds);
|
||||||
} else {
|
} else {
|
||||||
if (clipRectangle.Width != 0 && clipRectangle.Height != 0) {
|
if (clipRectangle.Width != 0 && clipRectangle.Height != 0) {
|
||||||
|
|
|
@ -40,7 +40,10 @@ namespace Greenshot.Drawing {
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(Graphics graphics, RenderMode renderMode) {
|
public override void Draw(Graphics graphics, RenderMode renderMode) {
|
||||||
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
|
||||||
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
|
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
|
||||||
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
|
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
|
||||||
|
|
|
@ -174,7 +174,9 @@ namespace Greenshot.Drawing {
|
||||||
/// <param name="graphics"></param>
|
/// <param name="graphics"></param>
|
||||||
/// <param name="renderMode"></param>
|
/// <param name="renderMode"></param>
|
||||||
public override void Draw(Graphics graphics, RenderMode renderMode) {
|
public override void Draw(Graphics graphics, RenderMode renderMode) {
|
||||||
graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
|
||||||
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
|
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
|
||||||
|
|
|
@ -24,6 +24,7 @@ using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
using Greenshot.Plugin.Drawing;
|
using Greenshot.Plugin.Drawing;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
|
||||||
namespace Greenshot.Drawing {
|
namespace Greenshot.Drawing {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -97,6 +98,10 @@ namespace Greenshot.Drawing {
|
||||||
|
|
||||||
public override void Draw(Graphics graphics, RenderMode rm) {
|
public override void Draw(Graphics graphics, RenderMode rm) {
|
||||||
if (icon != null) {
|
if (icon != null) {
|
||||||
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.Default;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
graphics.DrawIcon(icon, Bounds);
|
graphics.DrawIcon(icon, Bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,9 +56,11 @@ namespace Greenshot.Drawing {
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(Graphics graphics, RenderMode rm) {
|
public override void Draw(Graphics graphics, RenderMode rm) {
|
||||||
graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
|
||||||
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
|
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
|
||||||
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
|
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
|
||||||
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
||||||
|
|
|
@ -24,6 +24,7 @@ using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using Greenshot.Plugin.Drawing;
|
using Greenshot.Plugin.Drawing;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
|
||||||
namespace Greenshot.Drawing {
|
namespace Greenshot.Drawing {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -111,6 +112,10 @@ namespace Greenshot.Drawing {
|
||||||
|
|
||||||
public override void Draw(Graphics graphics, RenderMode rm) {
|
public override void Draw(Graphics graphics, RenderMode rm) {
|
||||||
if (metafile != null) {
|
if (metafile != null) {
|
||||||
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
graphics.DrawImage(metafile, Bounds);
|
graphics.DrawImage(metafile, Bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,12 @@ namespace Greenshot.Drawing {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void Draw(Graphics g, RenderMode rm) {
|
public override void Draw(Graphics graphics, RenderMode rm) {
|
||||||
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
|
||||||
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
|
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
|
||||||
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
|
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
|
||||||
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
|
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
|
||||||
|
@ -61,7 +66,7 @@ namespace Greenshot.Drawing {
|
||||||
this.Top + currentStep,
|
this.Top + currentStep,
|
||||||
this.Width,
|
this.Width,
|
||||||
this.Height);
|
this.Height);
|
||||||
g.DrawRectangle(shadowPen, shadowRect);
|
graphics.DrawRectangle(shadowPen, shadowRect);
|
||||||
currentStep++;
|
currentStep++;
|
||||||
alpha = alpha - (basealpha / steps);
|
alpha = alpha - (basealpha / steps);
|
||||||
}
|
}
|
||||||
|
@ -72,14 +77,14 @@ namespace Greenshot.Drawing {
|
||||||
|
|
||||||
if (!Color.Transparent.Equals(fillColor)) {
|
if (!Color.Transparent.Equals(fillColor)) {
|
||||||
using (Brush brush = new SolidBrush(fillColor)) {
|
using (Brush brush = new SolidBrush(fillColor)) {
|
||||||
g.FillRectangle(brush, rect);
|
graphics.FillRectangle(brush, rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lineThickness > 0) {
|
if (lineThickness > 0) {
|
||||||
using (Pen pen = new Pen(lineColor)) {
|
using (Pen pen = new Pen(lineColor)) {
|
||||||
pen.Width = lineThickness;
|
pen.Width = lineThickness;
|
||||||
g.DrawRectangle(pen, rect);
|
graphics.DrawRectangle(pen, rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -576,6 +576,9 @@ namespace Greenshot.Drawing {
|
||||||
MakeUndoable(new SurfaceBackgroundChangeMemento(this, offset), false);
|
MakeUndoable(new SurfaceBackgroundChangeMemento(this, offset), false);
|
||||||
SetImage(newImage, false);
|
SetImage(newImage, false);
|
||||||
Invalidate();
|
Invalidate();
|
||||||
|
if (SurfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, newImage.Size))) {
|
||||||
|
SurfaceSizeChanged(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,8 +607,9 @@ namespace Greenshot.Drawing {
|
||||||
|
|
||||||
public bool ApplyCrop(Rectangle cropRectangle) {
|
public bool ApplyCrop(Rectangle cropRectangle) {
|
||||||
if (isCropPossible(ref cropRectangle)) {
|
if (isCropPossible(ref cropRectangle)) {
|
||||||
|
Rectangle imageRectangle = new Rectangle(Point.Empty, Image.Size);
|
||||||
// we should not forget to Dispose the images!!
|
// we should not forget to Dispose the images!!
|
||||||
Bitmap tmpImage = ((Bitmap)Image).Clone(cropRectangle, Image.PixelFormat);
|
Bitmap tmpImage = ImageHelper.CloneArea(Image, cropRectangle, PixelFormat.DontCare);
|
||||||
tmpImage.SetResolution(Image.HorizontalResolution, Image.VerticalResolution);
|
tmpImage.SetResolution(Image.HorizontalResolution, Image.VerticalResolution);
|
||||||
|
|
||||||
Point offset = new Point(-cropRectangle.Left, -cropRectangle.Top);
|
Point offset = new Point(-cropRectangle.Left, -cropRectangle.Top);
|
||||||
|
@ -614,7 +618,7 @@ namespace Greenshot.Drawing {
|
||||||
|
|
||||||
SetImage(tmpImage, false);
|
SetImage(tmpImage, false);
|
||||||
elements.MoveBy(offset.X, offset.Y);
|
elements.MoveBy(offset.X, offset.Y);
|
||||||
if (SurfaceSizeChanged != null) {
|
if (SurfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, tmpImage.Size))) {
|
||||||
SurfaceSizeChanged(this);
|
SurfaceSizeChanged(this);
|
||||||
}
|
}
|
||||||
Invalidate();
|
Invalidate();
|
||||||
|
@ -799,14 +803,15 @@ namespace Greenshot.Drawing {
|
||||||
|
|
||||||
private Image GetImage(RenderMode renderMode) {
|
private Image GetImage(RenderMode renderMode) {
|
||||||
// Generate a copy of the original image with a dpi equal to the default...
|
// Generate a copy of the original image with a dpi equal to the default...
|
||||||
Bitmap clone = ImageHelper.CloneImageToBitmap(Image);
|
Bitmap clone = ImageHelper.Clone(Image);
|
||||||
// otherwise we would have a problem drawing the image to the surface... :(
|
// otherwise we would have a problem drawing the image to the surface... :(
|
||||||
using (Graphics graphics = Graphics.FromImage(clone)) {
|
using (Graphics graphics = Graphics.FromImage(clone)) {
|
||||||
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
// Do not set the following, the containers need to decide themselves
|
||||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
//graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
//graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
//graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
elements.Draw(graphics, (Bitmap)clone, renderMode, new Rectangle(Point.Empty, clone.Size));
|
//graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
elements.Draw(graphics, clone, renderMode, new Rectangle(Point.Empty, clone.Size));
|
||||||
}
|
}
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
@ -841,10 +846,11 @@ namespace Greenshot.Drawing {
|
||||||
}
|
}
|
||||||
// Elements might need the bitmap, so we copy the part we need
|
// Elements might need the bitmap, so we copy the part we need
|
||||||
using (Graphics graphics = Graphics.FromImage(buffer)) {
|
using (Graphics graphics = Graphics.FromImage(buffer)) {
|
||||||
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
// do not set the following, the containers need to decide this themselves!
|
||||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
//graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
//graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
//graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
//graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
graphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
|
graphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
|
||||||
graphics.SetClip(targetGraphics);
|
graphics.SetClip(targetGraphics);
|
||||||
elements.Draw(graphics, buffer, RenderMode.EDIT, clipRectangle);
|
elements.Draw(graphics, buffer, RenderMode.EDIT, clipRectangle);
|
||||||
|
@ -852,7 +858,7 @@ namespace Greenshot.Drawing {
|
||||||
targetGraphics.DrawImage(buffer, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
|
targetGraphics.DrawImage(buffer, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
|
||||||
} else {
|
} else {
|
||||||
// Only "simple" elements need to be redrawn, as the image is already drawn before getting the event we don't need the next line:
|
// Only "simple" elements need to be redrawn, as the image is already drawn before getting the event we don't need the next line:
|
||||||
//targetGraphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
|
// targetGraphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
|
||||||
elements.Draw(targetGraphics, null, RenderMode.EDIT, clipRectangle);
|
elements.Draw(targetGraphics, null, RenderMode.EDIT, clipRectangle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ using Greenshot.Drawing.Fields;
|
||||||
using Greenshot.Helpers;
|
using Greenshot.Helpers;
|
||||||
using Greenshot.Plugin.Drawing;
|
using Greenshot.Plugin.Drawing;
|
||||||
using Greenshot.Memento;
|
using Greenshot.Memento;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Drawing.Text;
|
||||||
|
|
||||||
namespace Greenshot.Drawing {
|
namespace Greenshot.Drawing {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -264,13 +266,18 @@ namespace Greenshot.Drawing {
|
||||||
HideTextBox();
|
HideTextBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(Graphics g, RenderMode rm) {
|
public override void Draw(Graphics graphics, RenderMode rm) {
|
||||||
base.Draw(g, rm);
|
base.Draw(graphics, rm);
|
||||||
UpdateFont();
|
UpdateFont();
|
||||||
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
graphics.TextRenderingHint = TextRenderingHint.SystemDefault;
|
||||||
|
|
||||||
Rectangle rect = GuiRectangle.GetGuiRectangle(this.Left, this.Top, this.Width, this.Height);
|
Rectangle rect = GuiRectangle.GetGuiRectangle(this.Left, this.Top, this.Width, this.Height);
|
||||||
if (Selected && rm == RenderMode.EDIT) {
|
if (Selected && rm == RenderMode.EDIT) {
|
||||||
DrawSelectionBorder(g, rect);
|
DrawSelectionBorder(graphics, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text == null || text.Length == 0 ) {
|
if (text == null || text.Length == 0 ) {
|
||||||
|
@ -295,7 +302,7 @@ namespace Greenshot.Drawing {
|
||||||
shadowRect.Inflate(-textOffset, -textOffset);
|
shadowRect.Inflate(-textOffset, -textOffset);
|
||||||
}
|
}
|
||||||
using (Brush fontBrush = new SolidBrush(Color.FromArgb(alpha, 100, 100, 100))) {
|
using (Brush fontBrush = new SolidBrush(Color.FromArgb(alpha, 100, 100, 100))) {
|
||||||
g.DrawString(text, font, fontBrush, shadowRect);
|
graphics.DrawString(text, font, fontBrush, shadowRect);
|
||||||
currentStep++;
|
currentStep++;
|
||||||
alpha = alpha - basealpha / steps;
|
alpha = alpha - basealpha / steps;
|
||||||
}
|
}
|
||||||
|
@ -308,7 +315,7 @@ namespace Greenshot.Drawing {
|
||||||
fontRect.Inflate(-textOffset,-textOffset);
|
fontRect.Inflate(-textOffset,-textOffset);
|
||||||
}
|
}
|
||||||
using (Brush fontBrush = new SolidBrush(lineColor)) {
|
using (Brush fontBrush = new SolidBrush(lineColor)) {
|
||||||
g.DrawString(text, font, fontBrush, fontRect);
|
graphics.DrawString(text, font, fontBrush, fontRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ namespace GreenshotNetworkImportPlugin {
|
||||||
// Convert byte[] to Image
|
// Convert byte[] to Image
|
||||||
memoryStream.Write(imageBytes, 0, imageBytes.Length);
|
memoryStream.Write(imageBytes, 0, imageBytes.Length);
|
||||||
using (Image image = Bitmap.FromStream(memoryStream, true)) {
|
using (Image image = Bitmap.FromStream(memoryStream, true)) {
|
||||||
ICapture capture = host.GetCapture(ImageHelper.CloneImageToBitmap(image));
|
ICapture capture = host.GetCapture(ImageHelper.Clone(image));
|
||||||
capture.CaptureDetails.Title = title;
|
capture.CaptureDetails.Title = title;
|
||||||
host.ImportCapture(capture);
|
host.ImportCapture(capture);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,7 @@ namespace GreenshotPlugin.Core {
|
||||||
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BitmapBuffer));
|
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BitmapBuffer));
|
||||||
private bool clone;
|
private bool clone;
|
||||||
private Bitmap bitmap;
|
private Bitmap bitmap;
|
||||||
public Bitmap Bitmap {
|
|
||||||
get {return bitmap;}
|
|
||||||
}
|
|
||||||
[NonSerialized]
|
[NonSerialized]
|
||||||
private BitmapData bmData;
|
private BitmapData bmData;
|
||||||
[NonSerialized]
|
[NonSerialized]
|
||||||
|
@ -113,31 +111,18 @@ namespace GreenshotPlugin.Core {
|
||||||
if (sourceRect.Height <= 0 || sourceRect.Width <= 0) {
|
if (sourceRect.Height <= 0 || sourceRect.Width <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SupportsPixelFormat(sourceBmp)) {
|
if (clone) {
|
||||||
if (clone) {
|
this.bitmap = ImageHelper.CloneArea(sourceBmp, sourceRect, PixelFormat.DontCare);
|
||||||
// Create copy with supported format
|
// Set "this" rect to location 0,0
|
||||||
this.bitmap = sourceBmp.Clone(sourceRect, sourceBmp.PixelFormat);
|
// as the Cloned Bitmap is only the part we want to work with
|
||||||
} else {
|
this.rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
|
||||||
this.bitmap = sourceBmp;
|
} else if (!ImageHelper.SupportsPixelFormat(sourceBmp)) {
|
||||||
}
|
throw new ArgumentException("Unsupported pixel format: " + sourceBmp.PixelFormat + " set clone to true!");
|
||||||
} else {
|
} else {
|
||||||
// We can only clone, as we don't support the pixel format!
|
this.bitmap = sourceBmp;
|
||||||
if (!clone) {
|
this.rect = sourceRect;
|
||||||
throw new ArgumentException("Not supported pixel format: " + sourceBmp.PixelFormat);
|
|
||||||
}
|
|
||||||
// When sourceRect is the whole bitmap there is a GDI+ bug in Clone
|
|
||||||
// Clone will than return the same PixelFormat as the source
|
|
||||||
// a quick workaround is using new Bitmap which uses a default of Format32bppArgb
|
|
||||||
if (sourceRect.Equals(bitmapRect)) {
|
|
||||||
this.bitmap = new Bitmap(sourceBmp);
|
|
||||||
} else {
|
|
||||||
this.bitmap = sourceBmp.Clone(sourceRect, PixelFormat.Format32bppArgb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Set "this" rect to location 0,0
|
|
||||||
// as the Cloned Bitmap is only the part we want to work with
|
|
||||||
this.rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -187,23 +172,29 @@ namespace GreenshotPlugin.Core {
|
||||||
* This is called when serializing the object
|
* This is called when serializing the object
|
||||||
*/
|
*/
|
||||||
public void GetObjectData(SerializationInfo info, StreamingContext ctxt) {
|
public void GetObjectData(SerializationInfo info, StreamingContext ctxt) {
|
||||||
Unlock();
|
bool isLocked = bitsLocked;
|
||||||
|
if (isLocked) {
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
info.AddValue("bitmap", this.bitmap);
|
info.AddValue("bitmap", this.bitmap);
|
||||||
|
if (isLocked) {
|
||||||
|
Lock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock the bitmap so we have direct access to the memory
|
* Lock the bitmap so we have direct access to the memory
|
||||||
*/
|
*/
|
||||||
public void Lock() {
|
public void Lock() {
|
||||||
if(rect.Width > 0 && rect.Height > 0) {
|
if(rect.Width > 0 && rect.Height > 0 && !bitsLocked) {
|
||||||
bmData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);
|
bmData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);
|
||||||
bitsLocked = true;
|
bitsLocked = true;
|
||||||
|
|
||||||
System.IntPtr Scan0 = bmData.Scan0;
|
IntPtr Scan0 = bmData.Scan0;
|
||||||
pointer = (byte*)(void*)Scan0;
|
pointer = (byte*)(void*)Scan0;
|
||||||
|
|
||||||
PrepareForPixelFormat();
|
PrepareForPixelFormat();
|
||||||
stride = bmData.Stride;
|
stride = bmData.Stride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +202,7 @@ namespace GreenshotPlugin.Core {
|
||||||
* Unlock the System Memory
|
* Unlock the System Memory
|
||||||
*/
|
*/
|
||||||
private void Unlock() {
|
private void Unlock() {
|
||||||
if(bitsLocked) {
|
if (bitsLocked) {
|
||||||
bitmap.UnlockBits(bmData);
|
bitmap.UnlockBits(bmData);
|
||||||
bitsLocked = false;
|
bitsLocked = false;
|
||||||
}
|
}
|
||||||
|
@ -242,14 +233,20 @@ namespace GreenshotPlugin.Core {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Make sure this.bitmap is unlocked
|
// Make sure this.bitmap is unlocked, if it was locked
|
||||||
Unlock();
|
bool isLocked = bitsLocked;
|
||||||
|
if (isLocked) {
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
if (destinationRect.HasValue) {
|
if (destinationRect.HasValue) {
|
||||||
graphics.DrawImage(this.bitmap, destinationRect.Value);
|
graphics.DrawImage(this.bitmap, destinationRect.Value);
|
||||||
} else if (destination.HasValue) {
|
} else if (destination.HasValue) {
|
||||||
graphics.DrawImage(this.bitmap, destination.Value);
|
graphics.DrawImageUnscaled(this.bitmap, destination.Value);
|
||||||
|
}
|
||||||
|
// If it was locked, lock it again
|
||||||
|
if (isLocked) {
|
||||||
|
Lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +301,7 @@ namespace GreenshotPlugin.Core {
|
||||||
int a = (aIndex==-1) ? 255 : (int)pointer[aIndex+offset];
|
int a = (aIndex==-1) ? 255 : (int)pointer[aIndex+offset];
|
||||||
return new int[]{a, pointer[rIndex+offset], pointer[gIndex+offset], pointer[bIndex+offset]};
|
return new int[]{a, pointer[rIndex+offset], pointer[gIndex+offset], pointer[bIndex+offset]};
|
||||||
} else {
|
} else {
|
||||||
return new int[]{0,0,0,0};
|
return new int[]{255,255,255,255};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,15 +319,6 @@ namespace GreenshotPlugin.Core {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the supplied Bitmap has a PixelFormat we support
|
|
||||||
*/
|
|
||||||
private bool SupportsPixelFormat(Bitmap bitmap) {
|
|
||||||
return (bitmap.PixelFormat.Equals(PixelFormat.Format32bppArgb) ||
|
|
||||||
bitmap.PixelFormat.Equals(PixelFormat.Format32bppRgb) ||
|
|
||||||
bitmap.PixelFormat.Equals(PixelFormat.Format24bppRgb));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set some internal values for accessing the bitmap according to the PixelFormat
|
* Set some internal values for accessing the bitmap according to the PixelFormat
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -80,7 +80,7 @@ namespace GreenshotPlugin.Core {
|
||||||
if (image != null && image is Bitmap && ((image.Width * image.Height) > 0)) {
|
if (image != null && image is Bitmap && ((image.Width * image.Height) > 0)) {
|
||||||
cropRectangle.Intersect(new Rectangle(0,0, image.Width, image.Height));
|
cropRectangle.Intersect(new Rectangle(0,0, image.Width, image.Height));
|
||||||
if (cropRectangle.Width != 0 || cropRectangle.Height != 0) {
|
if (cropRectangle.Width != 0 || cropRectangle.Height != 0) {
|
||||||
returnImage = (image as Bitmap).Clone(cropRectangle, image.PixelFormat);
|
returnImage = CloneArea(image, cropRectangle, PixelFormat.DontCare);
|
||||||
image.Dispose();
|
image.Dispose();
|
||||||
image = returnImage;
|
image = returnImage;
|
||||||
return true;
|
return true;
|
||||||
|
@ -90,6 +90,12 @@ namespace GreenshotPlugin.Core {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper method for the FindAutoCropRectangle
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer"></param>
|
||||||
|
/// <param name="colorPoint"></param>
|
||||||
|
/// <returns></returns>
|
||||||
private static Rectangle FindAutoCropRectangle(BitmapBuffer buffer, Point colorPoint) {
|
private static Rectangle FindAutoCropRectangle(BitmapBuffer buffer, Point colorPoint) {
|
||||||
Rectangle cropRectangle = Rectangle.Empty;
|
Rectangle cropRectangle = Rectangle.Empty;
|
||||||
Color referenceColor = buffer.GetColorAtWithoutAlpha(colorPoint.X,colorPoint.Y);
|
Color referenceColor = buffer.GetColorAtWithoutAlpha(colorPoint.X,colorPoint.Y);
|
||||||
|
@ -163,6 +169,11 @@ namespace GreenshotPlugin.Core {
|
||||||
return cropRectangle;
|
return cropRectangle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Load an image from file
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static Bitmap LoadBitmap(string filename) {
|
public static Bitmap LoadBitmap(string filename) {
|
||||||
if (string.IsNullOrEmpty(filename)) {
|
if (string.IsNullOrEmpty(filename)) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -179,7 +190,7 @@ namespace GreenshotPlugin.Core {
|
||||||
try {
|
try {
|
||||||
using (Image tmpImage = ExtractVistaIcon(imageFileStream)) {
|
using (Image tmpImage = ExtractVistaIcon(imageFileStream)) {
|
||||||
if (tmpImage != null) {
|
if (tmpImage != null) {
|
||||||
fileBitmap = CloneImageToBitmap(tmpImage);
|
fileBitmap = Clone(tmpImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception vistaIconException) {
|
} catch (Exception vistaIconException) {
|
||||||
|
@ -192,7 +203,7 @@ namespace GreenshotPlugin.Core {
|
||||||
// We create a copy of the bitmap, so everything else can be disposed
|
// We create a copy of the bitmap, so everything else can be disposed
|
||||||
using (Icon tmpIcon = new Icon(imageFileStream, new Size(1024,1024))) {
|
using (Icon tmpIcon = new Icon(imageFileStream, new Size(1024,1024))) {
|
||||||
using (Image tmpImage = tmpIcon.ToBitmap()) {
|
using (Image tmpImage = tmpIcon.ToBitmap()) {
|
||||||
fileBitmap = ImageHelper.CloneImageToBitmap(tmpImage);
|
fileBitmap = Clone(tmpImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception iconException) {
|
} catch (Exception iconException) {
|
||||||
|
@ -204,45 +215,13 @@ namespace GreenshotPlugin.Core {
|
||||||
// We create a copy of the bitmap, so everything else can be disposed
|
// We create a copy of the bitmap, so everything else can be disposed
|
||||||
imageFileStream.Position = 0;
|
imageFileStream.Position = 0;
|
||||||
using (Image tmpImage = Image.FromStream(imageFileStream, true, true)) {
|
using (Image tmpImage = Image.FromStream(imageFileStream, true, true)) {
|
||||||
fileBitmap = ImageHelper.CloneImageToBitmap(tmpImage);
|
fileBitmap = Clone(tmpImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fileBitmap;
|
return fileBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clone the image to a bitmap
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="srcImage">Image to clone</param>
|
|
||||||
/// <returns>Bitmap</returns>
|
|
||||||
public static Bitmap CloneImageToBitmap(Image srcImage) {
|
|
||||||
Bitmap returnImage;
|
|
||||||
int width = srcImage.Width;
|
|
||||||
int height = srcImage.Height;
|
|
||||||
float horizontalResolution = srcImage.HorizontalResolution;
|
|
||||||
float verticalResolution = srcImage.VerticalResolution;
|
|
||||||
PixelFormat pixelFormat = srcImage.PixelFormat;
|
|
||||||
if (srcImage is Metafile) {
|
|
||||||
pixelFormat = PixelFormat.Format32bppArgb;
|
|
||||||
}
|
|
||||||
// Make sure Greenshot supports the pixelformat, if not convert to one we support
|
|
||||||
if (!isSupported(pixelFormat)) {
|
|
||||||
pixelFormat = PixelFormat.Format24bppRgb;
|
|
||||||
}
|
|
||||||
returnImage = new Bitmap(width, height, pixelFormat);
|
|
||||||
returnImage.SetResolution(horizontalResolution, verticalResolution);
|
|
||||||
using (Graphics graphics = Graphics.FromImage(returnImage)) {
|
|
||||||
if (Image.IsAlphaPixelFormat(pixelFormat)) {
|
|
||||||
graphics.Clear(Color.Transparent);
|
|
||||||
} else {
|
|
||||||
graphics.Clear(Color.White);
|
|
||||||
}
|
|
||||||
graphics.DrawImageUnscaled(srcImage, 0, 0);
|
|
||||||
}
|
|
||||||
return returnImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if we support the supplied PixelFormat
|
* Checks if we support the supplied PixelFormat
|
||||||
*/
|
*/
|
||||||
|
@ -414,9 +393,9 @@ namespace GreenshotPlugin.Core {
|
||||||
nullColor = Color.Transparent;
|
nullColor = Color.Transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
using (BitmapBuffer bbbDest = new BitmapBuffer(sourceBitmap, applyRect)) {
|
using (BitmapBuffer bbbDest = new BitmapBuffer(sourceBitmap, applyRect, true)) {
|
||||||
bbbDest.Lock();
|
bbbDest.Lock();
|
||||||
using (BitmapBuffer bbbSrc = new BitmapBuffer(sourceBitmap, applyRect)) {
|
using (BitmapBuffer bbbSrc = new BitmapBuffer(sourceBitmap, applyRect, false)) {
|
||||||
bbbSrc.Lock();
|
bbbSrc.Lock();
|
||||||
Random rand = new Random();
|
Random rand = new Random();
|
||||||
|
|
||||||
|
@ -426,25 +405,25 @@ namespace GreenshotPlugin.Core {
|
||||||
long[] waSums = new long[wlen];
|
long[] waSums = new long[wlen];
|
||||||
long[] wcSums = new long[wlen];
|
long[] wcSums = new long[wlen];
|
||||||
long[] aSums = new long[wlen];
|
long[] aSums = new long[wlen];
|
||||||
long[] bSums = new long[wlen];
|
|
||||||
long[] gSums = new long[wlen];
|
|
||||||
long[] rSums = new long[wlen];
|
long[] rSums = new long[wlen];
|
||||||
|
long[] gSums = new long[wlen];
|
||||||
|
long[] bSums = new long[wlen];
|
||||||
for (int y = 0; y < applyRect.Height; ++y) {
|
for (int y = 0; y < applyRect.Height; ++y) {
|
||||||
long waSum = 0;
|
long waSum = 0;
|
||||||
long wcSum = 0;
|
long wcSum = 0;
|
||||||
long aSum = 0;
|
long aSum = 0;
|
||||||
long bSum = 0;
|
|
||||||
long gSum = 0;
|
|
||||||
long rSum = 0;
|
long rSum = 0;
|
||||||
|
long gSum = 0;
|
||||||
|
long bSum = 0;
|
||||||
|
|
||||||
for (int wx = 0; wx < wlen; ++wx) {
|
for (int wx = 0; wx < wlen; ++wx) {
|
||||||
int srcX = wx - r;
|
int srcX = wx - r;
|
||||||
waSums[wx] = 0;
|
waSums[wx] = 0;
|
||||||
wcSums[wx] = 0;
|
wcSums[wx] = 0;
|
||||||
aSums[wx] = 0;
|
aSums[wx] = 0;
|
||||||
bSums[wx] = 0;
|
|
||||||
gSums[wx] = 0;
|
|
||||||
rSums[wx] = 0;
|
rSums[wx] = 0;
|
||||||
|
gSums[wx] = 0;
|
||||||
|
bSums[wx] = 0;
|
||||||
|
|
||||||
if (srcX >= 0 && srcX < bbbDest.Width) {
|
if (srcX >= 0 && srcX < bbbDest.Width) {
|
||||||
for (int wy = 0; wy < wlen; ++wy) {
|
for (int wy = 0; wy < wlen; ++wy) {
|
||||||
|
@ -460,9 +439,9 @@ namespace GreenshotPlugin.Core {
|
||||||
wp >>= 8;
|
wp >>= 8;
|
||||||
|
|
||||||
aSums[wx] += wp * colors[0];
|
aSums[wx] += wp * colors[0];
|
||||||
bSums[wx] += wp * colors[3];
|
|
||||||
gSums[wx] += wp * colors[2];
|
|
||||||
rSums[wx] += wp * colors[1];
|
rSums[wx] += wp * colors[1];
|
||||||
|
gSums[wx] += wp * colors[2];
|
||||||
|
bSums[wx] += wp * colors[3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,24 +449,22 @@ namespace GreenshotPlugin.Core {
|
||||||
waSum += wwx * waSums[wx];
|
waSum += wwx * waSums[wx];
|
||||||
wcSum += wwx * wcSums[wx];
|
wcSum += wwx * wcSums[wx];
|
||||||
aSum += wwx * aSums[wx];
|
aSum += wwx * aSums[wx];
|
||||||
bSum += wwx * bSums[wx];
|
|
||||||
gSum += wwx * gSums[wx];
|
|
||||||
rSum += wwx * rSums[wx];
|
rSum += wwx * rSums[wx];
|
||||||
|
gSum += wwx * gSums[wx];
|
||||||
|
bSum += wwx * bSums[wx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wcSum >>= 8;
|
wcSum >>= 8;
|
||||||
|
|
||||||
if (waSum == 0 || wcSum == 0) {
|
if (parentBounds.Contains(applyRect.Left, applyRect.Top + y) ^ invert) {
|
||||||
if (parentBounds.Contains(applyRect.Left, applyRect.Top + y) ^ invert) {
|
if (waSum == 0 || wcSum == 0) {
|
||||||
bbbDest.SetColorAt(0, y, nullColor);
|
bbbDest.SetColorAt(0, y, nullColor);
|
||||||
}
|
} else {
|
||||||
} else {
|
int alpha = (int)(aSum / waSum);
|
||||||
int alpha = (int)(aSum / waSum);
|
int red = (int)(rSum / wcSum);
|
||||||
int blue = (int)(bSum / wcSum);
|
int green = (int)(gSum / wcSum);
|
||||||
int green = (int)(gSum / wcSum);
|
int blue = (int)(bSum / wcSum);
|
||||||
int red = (int)(rSum / wcSum);
|
|
||||||
if (parentBounds.Contains(applyRect.Left, applyRect.Top + y) ^ invert) {
|
|
||||||
bbbDest.SetColorAt(0, y, Color.FromArgb(alpha, red, green, blue));
|
bbbDest.SetColorAt(0, y, Color.FromArgb(alpha, red, green, blue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -497,17 +474,17 @@ namespace GreenshotPlugin.Core {
|
||||||
waSums[i] = waSums[i + 1];
|
waSums[i] = waSums[i + 1];
|
||||||
wcSums[i] = wcSums[i + 1];
|
wcSums[i] = wcSums[i + 1];
|
||||||
aSums[i] = aSums[i + 1];
|
aSums[i] = aSums[i + 1];
|
||||||
bSums[i] = bSums[i + 1];
|
|
||||||
gSums[i] = gSums[i + 1];
|
|
||||||
rSums[i] = rSums[i + 1];
|
rSums[i] = rSums[i + 1];
|
||||||
|
gSums[i] = gSums[i + 1];
|
||||||
|
bSums[i] = bSums[i + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
waSum = 0;
|
waSum = 0;
|
||||||
wcSum = 0;
|
wcSum = 0;
|
||||||
aSum = 0;
|
aSum = 0;
|
||||||
bSum = 0;
|
|
||||||
gSum = 0;
|
|
||||||
rSum = 0;
|
rSum = 0;
|
||||||
|
gSum = 0;
|
||||||
|
bSum = 0;
|
||||||
|
|
||||||
int wx;
|
int wx;
|
||||||
for (wx = 0; wx < wlen - 1; ++wx) {
|
for (wx = 0; wx < wlen - 1; ++wx) {
|
||||||
|
@ -515,9 +492,9 @@ namespace GreenshotPlugin.Core {
|
||||||
waSum += wwx * waSums[wx];
|
waSum += wwx * waSums[wx];
|
||||||
wcSum += wwx * wcSums[wx];
|
wcSum += wwx * wcSums[wx];
|
||||||
aSum += wwx * aSums[wx];
|
aSum += wwx * aSums[wx];
|
||||||
bSum += wwx * bSums[wx];
|
|
||||||
gSum += wwx * gSums[wx];
|
|
||||||
rSum += wwx * rSums[wx];
|
rSum += wwx * rSums[wx];
|
||||||
|
gSum += wwx * gSums[wx];
|
||||||
|
bSum += wwx * bSums[wx];
|
||||||
}
|
}
|
||||||
|
|
||||||
wx = wlen - 1;
|
wx = wlen - 1;
|
||||||
|
@ -525,9 +502,9 @@ namespace GreenshotPlugin.Core {
|
||||||
waSums[wx] = 0;
|
waSums[wx] = 0;
|
||||||
wcSums[wx] = 0;
|
wcSums[wx] = 0;
|
||||||
aSums[wx] = 0;
|
aSums[wx] = 0;
|
||||||
bSums[wx] = 0;
|
|
||||||
gSums[wx] = 0;
|
|
||||||
rSums[wx] = 0;
|
rSums[wx] = 0;
|
||||||
|
gSums[wx] = 0;
|
||||||
|
bSums[wx] = 0;
|
||||||
|
|
||||||
int srcX = x + wx - r;
|
int srcX = x + wx - r;
|
||||||
|
|
||||||
|
@ -545,9 +522,9 @@ namespace GreenshotPlugin.Core {
|
||||||
wp >>= 8;
|
wp >>= 8;
|
||||||
|
|
||||||
aSums[wx] += wp * (long)colors[0];
|
aSums[wx] += wp * (long)colors[0];
|
||||||
bSums[wx] += wp * (long)colors[3];
|
|
||||||
gSums[wx] += wp * (long)colors[2];
|
|
||||||
rSums[wx] += wp * (long)colors[1];
|
rSums[wx] += wp * (long)colors[1];
|
||||||
|
gSums[wx] += wp * (long)colors[2];
|
||||||
|
bSums[wx] += wp * (long)colors[3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -555,23 +532,20 @@ namespace GreenshotPlugin.Core {
|
||||||
waSum += (long)wr * waSums[wx];
|
waSum += (long)wr * waSums[wx];
|
||||||
wcSum += (long)wr * wcSums[wx];
|
wcSum += (long)wr * wcSums[wx];
|
||||||
aSum += (long)wr * aSums[wx];
|
aSum += (long)wr * aSums[wx];
|
||||||
bSum += (long)wr * bSums[wx];
|
|
||||||
gSum += (long)wr * gSums[wx];
|
|
||||||
rSum += (long)wr * rSums[wx];
|
rSum += (long)wr * rSums[wx];
|
||||||
|
gSum += (long)wr * gSums[wx];
|
||||||
|
bSum += (long)wr * bSums[wx];
|
||||||
}
|
}
|
||||||
|
|
||||||
wcSum >>= 8;
|
wcSum >>= 8;
|
||||||
|
if (parentBounds.Contains(applyRect.Left, applyRect.Top + y) ^ invert) {
|
||||||
if (waSum == 0 || wcSum == 0) {
|
if (waSum == 0 || wcSum == 0) {
|
||||||
if (parentBounds.Contains(applyRect.Left + x, applyRect.Top + y) ^ invert) {
|
|
||||||
bbbDest.SetColorAt(x, y, nullColor);
|
bbbDest.SetColorAt(x, y, nullColor);
|
||||||
}
|
} else {
|
||||||
} else {
|
int alpha = (int)(aSum / waSum);
|
||||||
int alpha = (int)(aSum / waSum);
|
int red = (int)(rSum / wcSum);
|
||||||
int blue = (int)(bSum / wcSum);
|
int green = (int)(gSum / wcSum);
|
||||||
int green = (int)(gSum / wcSum);
|
int blue = (int)(bSum / wcSum);
|
||||||
int red = (int)(rSum / wcSum);
|
|
||||||
if (parentBounds.Contains(applyRect.Left + x, applyRect.Top + y) ^ invert) {
|
|
||||||
bbbDest.SetColorAt(x, y, Color.FromArgb(alpha, red, green, blue));
|
bbbDest.SetColorAt(x, y, Color.FromArgb(alpha, red, green, blue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -731,5 +705,103 @@ namespace GreenshotPlugin.Core {
|
||||||
|
|
||||||
return newBitmap;
|
return newBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the supplied Bitmap has a PixelFormat we support
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bitmap">bitmap to check</param>
|
||||||
|
/// <returns>bool if we support it</returns>
|
||||||
|
public static bool SupportsPixelFormat(Bitmap bitmap) {
|
||||||
|
return SupportsPixelFormat(bitmap.PixelFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if we support the pixel format
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pixelformat">PixelFormat to check</param>
|
||||||
|
/// <returns>bool if we support it</returns>
|
||||||
|
public static bool SupportsPixelFormat(PixelFormat pixelformat) {
|
||||||
|
return (pixelformat.Equals(PixelFormat.Format32bppArgb) ||
|
||||||
|
pixelformat.Equals(PixelFormat.Format32bppRgb) ||
|
||||||
|
pixelformat.Equals(PixelFormat.Format24bppRgb));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wrapper for just cloning which calls the CloneArea
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceBitmap">Image to clone</param>
|
||||||
|
/// <returns>Bitmap with clone image data</returns>
|
||||||
|
public static Bitmap Clone(Image sourceBitmap) {
|
||||||
|
return CloneArea(sourceBitmap, Rectangle.Empty, PixelFormat.DontCare);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clone an image, taking some rules into account:
|
||||||
|
/// 1) When sourceRect is the whole bitmap there is a GDI+ bug in Clone
|
||||||
|
/// Clone will than return the same PixelFormat as the source
|
||||||
|
/// a quick workaround is using new Bitmap which uses a default of Format32bppArgb
|
||||||
|
/// 2) When going from a transparent to a non transparent bitmap, we draw the background white!
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceBitmap">Source bitmap to clone</param>
|
||||||
|
/// <param name="sourceRect">Rectangle to copy from the source, use Rectangle.Empty for all</param>
|
||||||
|
/// <param name="targetFormat">Target Format, use PixelFormat.DontCare if you want the original (or a default if the source PixelFormat is not supported)</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Bitmap CloneArea(Image sourceBitmap, Rectangle sourceRect, PixelFormat targetFormat) {
|
||||||
|
Bitmap newImage = null;
|
||||||
|
Rectangle bitmapRect = new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height);
|
||||||
|
|
||||||
|
// Make sure the source is not Rectangle.Empty
|
||||||
|
if (Rectangle.Empty.Equals(sourceRect)) {
|
||||||
|
sourceRect = new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no pixelformat is supplied
|
||||||
|
if (PixelFormat.DontCare == targetFormat || PixelFormat.Undefined == targetFormat) {
|
||||||
|
if (SupportsPixelFormat(sourceBitmap.PixelFormat)) {
|
||||||
|
targetFormat = sourceBitmap.PixelFormat;
|
||||||
|
} else if (Image.IsAlphaPixelFormat(sourceBitmap.PixelFormat)) {
|
||||||
|
targetFormat = PixelFormat.Format32bppArgb;
|
||||||
|
} else {
|
||||||
|
targetFormat = PixelFormat.Format24bppRgb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the target format
|
||||||
|
if (!SupportsPixelFormat(targetFormat)) {
|
||||||
|
if (Image.IsAlphaPixelFormat(targetFormat)) {
|
||||||
|
targetFormat = PixelFormat.Format32bppArgb;
|
||||||
|
} else {
|
||||||
|
targetFormat = PixelFormat.Format24bppRgb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool destinationIsTransparent = Image.IsAlphaPixelFormat(targetFormat);
|
||||||
|
bool sourceIsTransparent = Image.IsAlphaPixelFormat(sourceBitmap.PixelFormat);
|
||||||
|
bool fromTransparentToNon = !destinationIsTransparent && sourceIsTransparent;
|
||||||
|
bool isBitmap = sourceBitmap is Bitmap;
|
||||||
|
bool isAreaEqual = sourceRect.Equals(bitmapRect);
|
||||||
|
if (isAreaEqual || fromTransparentToNon || !isBitmap) {
|
||||||
|
// Rule 1: if the areas are equal, always copy ourselves
|
||||||
|
newImage = new Bitmap(bitmapRect.Width, bitmapRect.Height, targetFormat);
|
||||||
|
using (Graphics graphics = Graphics.FromImage(newImage)) {
|
||||||
|
if (fromTransparentToNon) {
|
||||||
|
// Rule 2: Make sure the background color is white
|
||||||
|
graphics.Clear(Color.White);
|
||||||
|
}
|
||||||
|
// decide fastest copy method
|
||||||
|
if (isAreaEqual) {
|
||||||
|
graphics.DrawImageUnscaled(sourceBitmap, 0, 0);
|
||||||
|
} else {
|
||||||
|
graphics.DrawImage(sourceBitmap, 0, 0, sourceRect, GraphicsUnit.Pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Let GDI+ decide how to convert, need to test what is quicker...
|
||||||
|
newImage = (sourceBitmap as Bitmap).Clone(sourceRect, targetFormat);
|
||||||
|
}
|
||||||
|
// Make sure both images have the same resolution
|
||||||
|
newImage.SetResolution(sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution);
|
||||||
|
return newImage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,7 +209,12 @@ namespace Greenshot.Interop {
|
||||||
private void Dispose(bool disposing) {
|
private void Dispose(bool disposing) {
|
||||||
if (null != this._COMObject) {
|
if (null != this._COMObject) {
|
||||||
if(Marshal.IsComObject(this._COMObject)) {
|
if(Marshal.IsComObject(this._COMObject)) {
|
||||||
while( Marshal.ReleaseComObject(this._COMObject) > 0 );
|
try {
|
||||||
|
while (Marshal.ReleaseComObject(this._COMObject) > 0) ;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LOG.WarnFormat("Problem releasing {0}", _COMType);
|
||||||
|
LOG.Warn("Error: ", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._COMObject = null;
|
this._COMObject = null;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue