【发布时间】:2014-03-20 15:45:29
【问题描述】:
我正在创建一个类似于 windows 7 截图工具的新截图工具。
但是我不能让高亮效果发挥同样的作用。
例如,截图工具高亮的工作原理如下:(高亮在白色背景上非常亮,看起来没有透明度
我的截图工具高亮如下:
我确定使用的颜色相同 (255,255,0),alpha 通道为 110。如果我降低透明度,那么它只会覆盖下面的文本。
我的截图是在白色的顶部应用透明度,而 windows 截图工具似乎可以更好地融合它。
我在这里做错了什么?
我用于高亮注释的代码是:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Sicon.Snipper.Annotations
{
/// <summary>
/// Highlight Annotation
/// </summary>
public class HighlightAnnotation : BaseAnnotation
{
#region Members
protected Rectangle _selection = Rectangle.Empty;
protected const int _transparancyAlpha = 110;
private Brush _brush;
#endregion Members
#region Properties
/// <summary>
/// Gets or Sets the Brush
/// </summary>
protected Brush Brush
{
get { return _brush; }
set { _brush = value; }
}
/// <summary>
/// Gets the Selection
/// </summary>
public Rectangle Selection
{
get { return _selection; }
protected set { _selection = value; }
}
#endregion Properties
#region Constructors
/// <summary>
/// Constructor
/// </summary>
/// <param name="imageRef">Reference to the image</param>
public HighlightAnnotation(Image imageRef, Control host)
: base(imageRef, Pens.Yellow, host)
{
this.Brush = new SolidBrush(
Color.FromArgb(
_transparancyAlpha,
this.Pen.Color));
}
#endregion Constructors
#region Methods
/// <summary>
/// Handles on Mouse down
/// </summary>
/// <param name="e">args</param>
public override void OnMouseDown(MouseEventArgs e)
{
if (base.Enabled)
{
// Start the snip on mouse down
if (e.Button != MouseButtons.Left) return;
_startPoint = e.Location;
_selection = new Rectangle(e.Location, new Size(0, 0));
}
}
/// <summary>
/// Handles Mouse Move
/// </summary>
/// <param name="e">args</param>
public override void OnMouseMove(MouseEventArgs e)
{
if (base.Enabled)
{
// Modify the selection on mouse move
if (e.Button != MouseButtons.Left) return;
int x1 = Math.Min(e.X, _startPoint.X);
int y1 = Math.Min(e.Y, _startPoint.Y);
int x2 = Math.Max(e.X, _startPoint.X);
int y2 = Math.Max(e.Y, _startPoint.Y);
_selection = new Rectangle(x1, y1, x2 - x1, y2 - y1);
}
}
/// <summary>
/// Handles on mouse up
/// </summary>
/// <param name="e">args</param>
public override void OnMouseUp(MouseEventArgs e)
{
if (base.Enabled)
{
if (_selection.Width <= 0 || _selection.Height <= 0) return;
using (Graphics g = Graphics.FromImage(this.ImageRef))
{
Rectangle dest = new Rectangle(
TranslateCenterImageMousePosition(_startPoint),
_selection.Size);
g.FillRectangle(
this.Brush,
dest);
}
this.Enabled = false;
}
}
/// <summary>
/// Hanles on paint
/// </summary>
/// <param name="g">graphics</param>
public override void OnPaint(System.Drawing.Graphics g)
{
if (base.Enabled)
g.FillRectangle(this.Brush, _selection);
}
#endregion Methods
}
}
更新::
好的,我做了一些改变,我也喜欢手绘的想法,但我这样做的主要原因是有漂亮整洁的亮点等。
我现在遇到的问题是,当我释放鼠标按钮时,矩形被绘制为黑色,如下图所示。快到了!
GDI32.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace Sicon.Snipper.Tools
{
public static class GDI32
{
[DllImport("gdi32.dll")]
public static extern int SetROP2(IntPtr hdc, int fnDrawMode);
[DllImport("gdi32.dll")]
public static extern IntPtr CreatePen(int fnPenStyle, int nWidth, uint crColor);
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
public static extern bool MoveToEx(IntPtr hdc, int X, int Y, IntPtr lpPoint);
[DllImport("gdi32.dll")]
public static extern bool LineTo(IntPtr hdc, int nXEnd, int nYEnd);
[DllImport("gdi32.dll")]
public static extern bool Rectangle(IntPtr hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
}
}
新的Hightlight Annotation.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Sicon.Snipper.Enums;
using Sicon.Snipper.Tools;
namespace Sicon.Snipper.Annotations
{
/// <summary>
/// Highlight Annotation
/// </summary>
public class HighlightAnnotation : BaseAnnotation
{
#region Members
protected Rectangle _selection = Rectangle.Empty;
protected const int _transparancyAlpha = 110;
private ShapeEnum _shape = ShapeEnum.Rectangle;
List<Point> points = new List<Point>();
private const int PS_SOLID = 0;
private const int R2_MASKPEN = 9;
private const int R2_COPYPEN = 13;
#endregion Members
#region Properties
/// <summary>
/// Gets or Sets the Shape
/// </summary>
public ShapeEnum Shape
{
get { return _shape; }
set { _shape = value; }
}
/// <summary>
/// Gets the Selection
/// </summary>
public Rectangle Selection
{
get { return _selection; }
protected set { _selection = value; }
}
#endregion Properties
#region Constructors
/// <summary>
/// Constructor
/// </summary>
/// <param name="imageRef">Reference to the image</param>
public HighlightAnnotation(Image imageRef, Control host, ShapeEnum shape)
: base(imageRef, new Pen(Color.Yellow, 16), host)
{
_shape = shape;
}
#endregion Constructors
#region Methods
/// <summary>
/// Handles on Mouse down
/// </summary>
/// <param name="e">args</param>
public override void OnMouseDown(MouseEventArgs e)
{
if (base.Enabled)
{
// Start the snip on mouse down
if (e.Button != MouseButtons.Left) return;
_startPoint = e.Location;
_selection = new Rectangle(e.Location, new Size(0, 0));
}
}
/// <summary>
/// Handles Mouse Move
/// </summary>
/// <param name="e">args</param>
public override void OnMouseMove(MouseEventArgs e)
{
if (base.Enabled)
{
// Modify the selection on mouse move
if (e.Button != MouseButtons.Left) return;
//Add freehand points
points.Add(new Point(e.X, e.Y));
//Update selection rectangele
int x1 = Math.Min(e.X, _startPoint.X);
int y1 = Math.Min(e.Y, _startPoint.Y);
int x2 = Math.Max(e.X, _startPoint.X);
int y2 = Math.Max(e.Y, _startPoint.Y);
_selection = new Rectangle(x1, y1, x2 - x1, y2 - y1);
}
}
/// <summary>
/// Handles on mouse up
/// </summary>
/// <param name="e">args</param>
public override void OnMouseUp(MouseEventArgs e)
{
if (base.Enabled)
{
if (_selection.Width <= 0 || _selection.Height <= 0) return;
using (Graphics g = Graphics.FromImage(this.ImageRef))
{
switch (this.Shape)
{
case ShapeEnum.Freehand:
DrawHighlight(g, points.ToArray());
break;
case ShapeEnum.Rectangle:
Rectangle dest = new Rectangle(
TranslateCenterImageMousePosition(_startPoint),
_selection.Size);
DrawRectange(g);
break;
default: return;
}
}
this.Enabled = false;
}
}
/// <summary>
/// Hanles on paint
/// </summary>
/// <param name="g">graphics</param>
public override void OnPaint(System.Drawing.Graphics g)
{
if (base.Enabled)
{
switch (this.Shape)
{
case ShapeEnum.Freehand:
DrawHighlight(g, points.ToArray());
break;
case ShapeEnum.Rectangle:
DrawRectange(g);
break;
default: return;
}
}
}
/// <summary>
/// Draws a highlight
/// </summary>
/// <param name="g">graphics</param>
/// <param name="usePoints">points to draw</param>
private void DrawHighlight(Graphics g, Point[] usePoints)
{
int useColor = System.Drawing.ColorTranslator.ToWin32(base.Pen.Color);
IntPtr pen = GDI32.CreatePen(PS_SOLID, (int)base.Pen.Width, (uint)useColor);
IntPtr hDC = g.GetHdc();
IntPtr xDC = GDI32.SelectObject(hDC, pen);
GDI32.SetROP2(hDC, R2_MASKPEN);
for (int i = 1; i <= usePoints.Length - 1; i++)
{
Point p1 = usePoints[i - 1];
Point p2 = usePoints[i];
GDI32.MoveToEx(hDC, p1.X, p1.Y, IntPtr.Zero);
GDI32.LineTo(hDC, p2.X, p2.Y);
}
GDI32.SetROP2(hDC, R2_COPYPEN);
GDI32.SelectObject(hDC, xDC);
GDI32.DeleteObject(pen);
g.ReleaseHdc(hDC);
}
/// <summary>
/// Draws a rectangle
/// </summary>
/// <param name="g">Graphics</param>
private void DrawRectange(Graphics g)
{
Rectangle dest = new Rectangle(
TranslateCenterImageMousePosition(_startPoint),
_selection.Size);
int useColor = System.Drawing.ColorTranslator.ToWin32(base.Pen.Color);
IntPtr pen = GDI32.CreatePen(PS_SOLID, (int)base.Pen.Width, (uint)useColor);
IntPtr hDC = g.GetHdc();
IntPtr xDC = GDI32.SelectObject(hDC, pen);
GDI32.SetROP2(hDC, R2_MASKPEN);
GDI32.Rectangle(hDC, dest.Left, dest.Top, dest.Right, dest.Bottom);
GDI32.SetROP2(hDC, R2_COPYPEN);
GDI32.SelectObject(hDC, xDC);
GDI32.DeleteObject(pen);
g.ReleaseHdc(hDC);
}
#endregion Methods
}
}
【问题讨论】: