mirror of
https://github.com/greenshot/greenshot
synced 2025-07-14 17:13:44 -07:00
Small fixes in GraphicsPath usage, making sure they are disposed. Also making sure Anti-Aliasing is used when drawing the shadow.
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@1644 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
5aa6249231
commit
8374aa5fb6
7 changed files with 100 additions and 78 deletions
|
@ -102,11 +102,12 @@ namespace Greenshot.Drawing {
|
||||||
using (Pen pen = new Pen(Color.White)) {
|
using (Pen pen = new Pen(Color.White)) {
|
||||||
pen.Width = lineThickness;
|
pen.Width = lineThickness;
|
||||||
SetArrowHeads((ArrowHeadCombination)GetFieldValue(FieldType.ARROWHEADS), pen);
|
SetArrowHeads((ArrowHeadCombination)GetFieldValue(FieldType.ARROWHEADS), pen);
|
||||||
GraphicsPath path = new GraphicsPath();
|
using (GraphicsPath path = new GraphicsPath()) {
|
||||||
path.AddLine(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
|
path.AddLine(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
|
||||||
Rectangle drawingBounds = Rectangle.Round(path.GetBounds(new Matrix(), pen));
|
Rectangle drawingBounds = Rectangle.Round(path.GetBounds(new Matrix(), pen));
|
||||||
drawingBounds.Inflate(2,2);
|
drawingBounds.Inflate(2, 2);
|
||||||
return drawingBounds;
|
return drawingBounds;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Rectangle.Empty;
|
return Rectangle.Empty;
|
||||||
|
@ -120,9 +121,10 @@ namespace Greenshot.Drawing {
|
||||||
using (Pen pen = new Pen(Color.White)) {
|
using (Pen pen = new Pen(Color.White)) {
|
||||||
pen.Width = lineThickness;
|
pen.Width = lineThickness;
|
||||||
SetArrowHeads((ArrowHeadCombination)GetFieldValue(FieldType.ARROWHEADS), pen);
|
SetArrowHeads((ArrowHeadCombination)GetFieldValue(FieldType.ARROWHEADS), pen);
|
||||||
GraphicsPath path = new GraphicsPath();
|
using (GraphicsPath path = new GraphicsPath()) {
|
||||||
path.AddLine(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
|
path.AddLine(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
|
||||||
return path.IsOutlineVisible(x,y, pen);
|
return path.IsOutlineVisible(x, y, pen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -103,9 +103,10 @@ namespace Greenshot.Drawing {
|
||||||
if (lineThickness > 0) {
|
if (lineThickness > 0) {
|
||||||
using (Pen pen = new Pen(Color.White)) {
|
using (Pen pen = new Pen(Color.White)) {
|
||||||
pen.Width = lineThickness;
|
pen.Width = lineThickness;
|
||||||
GraphicsPath path = new GraphicsPath();
|
using (GraphicsPath path = new GraphicsPath()) {
|
||||||
path.AddEllipse(rect);
|
path.AddEllipse(rect);
|
||||||
return path.IsOutlineVisible(x, y, pen);
|
return path.IsOutlineVisible(x, y, pen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -98,9 +98,10 @@ namespace Greenshot.Drawing {
|
||||||
if (lineThickness > 0) {
|
if (lineThickness > 0) {
|
||||||
using (Pen pen = new Pen(Color.White)) {
|
using (Pen pen = new Pen(Color.White)) {
|
||||||
pen.Width = lineThickness;
|
pen.Width = lineThickness;
|
||||||
GraphicsPath path = new GraphicsPath();
|
using (GraphicsPath path = new GraphicsPath()) {
|
||||||
path.AddLine(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
|
path.AddLine(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
|
||||||
return path.IsOutlineVisible(x,y, pen);
|
return path.IsOutlineVisible(x, y, pen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -100,9 +100,10 @@ namespace Greenshot.Drawing {
|
||||||
if (lineThickness > 0) {
|
if (lineThickness > 0) {
|
||||||
using (Pen pen = new Pen(Color.White)) {
|
using (Pen pen = new Pen(Color.White)) {
|
||||||
pen.Width = lineThickness;
|
pen.Width = lineThickness;
|
||||||
GraphicsPath path = new GraphicsPath();
|
using (GraphicsPath path = new GraphicsPath()) {
|
||||||
path.AddRectangle(rect);
|
path.AddRectangle(rect);
|
||||||
return path.IsOutlineVisible(x, y, pen);
|
return path.IsOutlineVisible(x, y, pen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -567,6 +567,7 @@ namespace Greenshot.Drawing {
|
||||||
// Make undoable
|
// Make undoable
|
||||||
MakeUndoable(new SurfaceCropMemento(this, imageRectangle), false);
|
MakeUndoable(new SurfaceCropMemento(this, imageRectangle), false);
|
||||||
SetImage(newImage, false);
|
SetImage(newImage, false);
|
||||||
|
Invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1171,10 +1171,12 @@ namespace Greenshot {
|
||||||
|
|
||||||
void TornEdgeToolStripMenuItemClick(object sender, EventArgs e) {
|
void TornEdgeToolStripMenuItemClick(object sender, EventArgs e) {
|
||||||
surface.ApplyBitmapEffect(Effects.TornEdge);
|
surface.ApplyBitmapEffect(Effects.TornEdge);
|
||||||
|
updateUndoRedoSurfaceDependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowToolStripMenuItemClick(object sender, EventArgs e) {
|
void ShadowToolStripMenuItemClick(object sender, EventArgs e) {
|
||||||
surface.ApplyBitmapEffect(Effects.Shadow);
|
surface.ApplyBitmapEffect(Effects.Shadow);
|
||||||
|
updateUndoRedoSurfaceDependencies();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,62 +311,64 @@ namespace GreenshotPlugin.Core {
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOG.Warn("An exception occured while setting the resolution.", ex);
|
LOG.Warn("An exception occured while setting the resolution.", ex);
|
||||||
}
|
}
|
||||||
GraphicsPath path = new GraphicsPath();
|
using (GraphicsPath path = new GraphicsPath()) {
|
||||||
Random random = new Random();
|
Random random = new Random();
|
||||||
int regionWidth = 20;
|
int regionWidth = 20;
|
||||||
int regionHeight = 20;
|
int regionHeight = 20;
|
||||||
int HorizontalRegions = (int)(sourceBitmap.Width / regionWidth);
|
int HorizontalRegions = (int)(sourceBitmap.Width / regionWidth);
|
||||||
int VerticalRegions = (int)(sourceBitmap.Height / regionHeight);
|
int VerticalRegions = (int)(sourceBitmap.Height / regionHeight);
|
||||||
int distance = 12;
|
int distance = 12;
|
||||||
|
|
||||||
// Start
|
// Start
|
||||||
Point previousEndingPoint = new Point(regionWidth, random.Next(1, distance));
|
Point previousEndingPoint = new Point(regionWidth, random.Next(1, distance));
|
||||||
Point newEndingPoint;
|
Point newEndingPoint;
|
||||||
// Top
|
// Top
|
||||||
for (int i = 0; i < HorizontalRegions; i++) {
|
for (int i = 0; i < HorizontalRegions; i++) {
|
||||||
int x = (int)previousEndingPoint.X + regionWidth;
|
int x = (int)previousEndingPoint.X + regionWidth;
|
||||||
int y = random.Next(1, distance);
|
int y = random.Next(1, distance);
|
||||||
newEndingPoint = new Point(x, y);
|
newEndingPoint = new Point(x, y);
|
||||||
path.AddLine(previousEndingPoint, newEndingPoint);
|
path.AddLine(previousEndingPoint, newEndingPoint);
|
||||||
previousEndingPoint = newEndingPoint;
|
previousEndingPoint = newEndingPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right
|
// Right
|
||||||
for (int i = 0; i < VerticalRegions; i++) {
|
for (int i = 0; i < VerticalRegions; i++) {
|
||||||
int x = sourceBitmap.Width - random.Next(1, distance);
|
int x = sourceBitmap.Width - random.Next(1, distance);
|
||||||
int y = (int)previousEndingPoint.Y + regionHeight;
|
int y = (int)previousEndingPoint.Y + regionHeight;
|
||||||
newEndingPoint = new Point(x, y);
|
newEndingPoint = new Point(x, y);
|
||||||
path.AddLine(previousEndingPoint, newEndingPoint);
|
path.AddLine(previousEndingPoint, newEndingPoint);
|
||||||
previousEndingPoint = newEndingPoint;
|
previousEndingPoint = newEndingPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bottom
|
// Bottom
|
||||||
for (int i = 0; i < HorizontalRegions; i++) {
|
for (int i = 0; i < HorizontalRegions; i++) {
|
||||||
int x = (int)previousEndingPoint.X - regionWidth;
|
int x = (int)previousEndingPoint.X - regionWidth;
|
||||||
int y = sourceBitmap.Height - random.Next(1, distance);
|
int y = sourceBitmap.Height - random.Next(1, distance);
|
||||||
newEndingPoint = new Point(x, y);
|
newEndingPoint = new Point(x, y);
|
||||||
path.AddLine(previousEndingPoint, newEndingPoint);
|
path.AddLine(previousEndingPoint, newEndingPoint);
|
||||||
previousEndingPoint = newEndingPoint;
|
previousEndingPoint = newEndingPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Left
|
// Left
|
||||||
for (int i = 0; i < VerticalRegions; i++) {
|
for (int i = 0; i < VerticalRegions; i++) {
|
||||||
int x = random.Next(1, distance);
|
int x = random.Next(1, distance);
|
||||||
int y = (int)previousEndingPoint.Y - regionHeight;
|
int y = (int)previousEndingPoint.Y - regionHeight;
|
||||||
newEndingPoint = new Point(x, y);
|
newEndingPoint = new Point(x, y);
|
||||||
path.AddLine(previousEndingPoint, newEndingPoint);
|
path.AddLine(previousEndingPoint, newEndingPoint);
|
||||||
previousEndingPoint = newEndingPoint;
|
previousEndingPoint = newEndingPoint;
|
||||||
}
|
}
|
||||||
path.CloseFigure();
|
path.CloseFigure();
|
||||||
|
|
||||||
// Draw
|
// Draw the created figure with the original image by using a TextureBrush so we have anti-aliasing
|
||||||
using (Graphics graphics = Graphics.FromImage(returnImage)) {
|
using (Graphics graphics = Graphics.FromImage(returnImage)) {
|
||||||
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
using (Brush brush = new TextureBrush(sourceBitmap)) {
|
using (Brush brush = new TextureBrush(sourceBitmap)) {
|
||||||
graphics.FillPath(brush, path);
|
// Imporant note: If the target wouldn't be at 0,0 we need to translate-transform!!
|
||||||
|
graphics.FillPath(brush, path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return returnImage;
|
return returnImage;
|
||||||
|
@ -611,19 +613,26 @@ namespace GreenshotPlugin.Core {
|
||||||
/// <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(Bitmap sourceBitmap, float darkness, int shadowSize, PixelFormat targetPixelformat, out Point offset) {
|
public static Bitmap CreateShadow(Bitmap sourceBitmap, float darkness, int shadowSize, PixelFormat targetPixelformat, out Point offset) {
|
||||||
|
// "return" the shifted offset, so the caller can e.g. move elements
|
||||||
|
offset = new Point(shadowSize - 2, shadowSize - 2);
|
||||||
|
|
||||||
|
// Create a new "clean" image
|
||||||
Bitmap newImage = new Bitmap(sourceBitmap.Width + (shadowSize * 2), sourceBitmap.Height + (shadowSize * 2), targetPixelformat);
|
Bitmap newImage = new Bitmap(sourceBitmap.Width + (shadowSize * 2), sourceBitmap.Height + (shadowSize * 2), targetPixelformat);
|
||||||
|
|
||||||
using (Graphics graphics = Graphics.FromImage(newImage)) {
|
using (Graphics graphics = Graphics.FromImage(newImage)) {
|
||||||
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
// Make sure the background color is what we want (transparent or white, depending on the pixel format)
|
||||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
|
||||||
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
|
||||||
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
||||||
|
|
||||||
if (Image.IsAlphaPixelFormat(targetPixelformat)) {
|
if (Image.IsAlphaPixelFormat(targetPixelformat)) {
|
||||||
graphics.Clear(Color.Transparent);
|
graphics.Clear(Color.Transparent);
|
||||||
} else {
|
} else {
|
||||||
graphics.Clear(Color.White);
|
graphics.Clear(Color.White);
|
||||||
}
|
}
|
||||||
|
// Make sure we draw with the best quality!
|
||||||
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
|
||||||
|
// Draw "shadow" offsetted
|
||||||
ImageAttributes ia = new ImageAttributes();
|
ImageAttributes ia = new ImageAttributes();
|
||||||
ColorMatrix cm = new ColorMatrix();
|
ColorMatrix cm = new ColorMatrix();
|
||||||
cm.Matrix00 = 0;
|
cm.Matrix00 = 0;
|
||||||
|
@ -631,14 +640,19 @@ namespace GreenshotPlugin.Core {
|
||||||
cm.Matrix22 = 0;
|
cm.Matrix22 = 0;
|
||||||
cm.Matrix33 = darkness;
|
cm.Matrix33 = darkness;
|
||||||
ia.SetColorMatrix(cm);
|
ia.SetColorMatrix(cm);
|
||||||
// Draw "shadow" offsetted
|
Point shadowLocation = new Point(shadowSize, shadowSize);
|
||||||
graphics.DrawImage(sourceBitmap, new Rectangle(new Point(shadowSize, shadowSize), sourceBitmap.Size), 0, 0, sourceBitmap.Width, sourceBitmap.Height, GraphicsUnit.Pixel, ia);
|
graphics.DrawImage(sourceBitmap, new Rectangle(shadowLocation, sourceBitmap.Size), 0, 0, sourceBitmap.Width, sourceBitmap.Height, GraphicsUnit.Pixel, ia);
|
||||||
|
|
||||||
// blur "shadow", apply to whole new image
|
// blur "shadow", apply to whole new image
|
||||||
Rectangle applyRectangle = new Rectangle(Point.Empty, newImage.Size);
|
Rectangle applyRectangle = new Rectangle(Point.Empty, newImage.Size);
|
||||||
ApplyBlur(graphics, newImage, applyRectangle, true, shadowSize, 1d, false, applyRectangle);
|
ApplyBlur(graphics, newImage, applyRectangle, true, shadowSize, 1d, false, applyRectangle);
|
||||||
// draw original
|
|
||||||
offset = new Point(shadowSize - 2, shadowSize - 2);
|
// draw original with a TextureBrush so we have nice antialiasing!
|
||||||
graphics.DrawImage(sourceBitmap, offset);
|
using (Brush textureBrush = new TextureBrush(sourceBitmap, WrapMode.Clamp)) {
|
||||||
|
// We need to do a translate-tranform otherwise the image is wrapped
|
||||||
|
graphics.TranslateTransform(shadowSize - 2, shadowSize - 2);
|
||||||
|
graphics.FillRectangle(textureBrush, 0, 0, sourceBitmap.Width, sourceBitmap.Height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return newImage;
|
return newImage;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue