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:
RKrom 2012-02-09 08:52:58 +00:00
parent 5aa6249231
commit 8374aa5fb6
7 changed files with 100 additions and 78 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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();
} }
} }

View file

@ -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();
} }
} }
} }

View file

@ -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;
} }