C# 突出显示效果,如剪断工具
我正在创建一个新的剪贴工具,类似于Windows7剪贴工具 然而,我不能得到同样的高光效果 例如,剪切工具“高光”的工作原理如下:(高光在白色背景上非常明亮,看起来没有透明度 我的剪贴工具高亮显示如下: 我确信使用的颜色是相同的(255255,0),alpha通道为110。如果我降低透明度,它只会覆盖下面的文本 我的剪贴画将透明度应用到白色的顶部,而windows剪贴工具似乎将其更好地融合在一起 我做错了什么 我用于突出显示批注的代码是:C# 突出显示效果,如剪断工具,c#,winforms,graphics,C#,Winforms,Graphics,我正在创建一个新的剪贴工具,类似于Windows7剪贴工具 然而,我不能得到同样的高光效果 例如,剪切工具“高光”的工作原理如下:(高光在白色背景上非常明亮,看起来没有透明度 我的剪贴工具高亮显示如下: 我确信使用的颜色是相同的(255255,0),alpha通道为110。如果我降低透明度,它只会覆盖下面的文本 我的剪贴画将透明度应用到白色的顶部,而windows剪贴工具似乎将其更好地融合在一起 我做错了什么 我用于突出显示批注的代码是: using System; using System
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
}
}
新的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
}
}
使用系统;
使用System.Collections.Generic;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
使用Sicon.Snipper.Enums;
使用Sicon.Snipper.Tools;
命名空间Sicon.Snipper.Annotations
{
///
///突出显示注释
///
公共类HighlightAnnotation:BaseAnnotation
{
#区域成员
受保护矩形_selection=Rectangle.Empty;
保护常数int_transparancyAlpha=110;
私有shapenum _shape=shapenum.Rectangle;
列表点=新列表();
私有常量int PS_SOLID=0;
私有常量int R2_MASKPEN=9;
私有常量int R2_COPYPEN=13;
#端区成员
#区域属性
///
///获取或设置形状
///
公共形状
{
获取{return\u shape;}
设置{u shape=value;}
}
///
///获取所选内容
///
公共矩形选择
{
获取{return\u selection;}
受保护集{u selection=value;}
}
#端域属性
#区域构造函数
///
///建造师
///
///对图像的引用
公共HighlightAnnotation(图像imageRef、控件主机、ShapeEnum形状)
:底座(imageRef,新笔(颜色:黄色,16),主机)
{
_形状=形状;
}
#端域构造函数
#区域方法
///
///把手放在鼠标下
///
///args
MouseDown上的公共覆盖无效(MouseEventArgs e)
{
如果(基本启用)
{
//开始剪断鼠标
如果(e.Button!=MouseButtons.Left)返回;
_起始点=e.位置;
_选择=新矩形(例如位置,新大小(0,0));
}
}
///
///控制鼠标移动
///
///args
mouseMove上的公共覆盖无效(MouseEventArgs e)
{
如果(基本启用)
{
//在鼠标移动时修改选择
如果(e.Button!=MouseButtons.Left)返回;
//添加徒手点
增加(新点(e.X,e.Y));
//更新选择矩形
int x1=数学最小值(e.X,_startPoint.X);
int y1=数学最小值(e.Y,_startPoint.Y);
int x2=数学最大值(e.X,_startPoint.X);
int y2=数学最大值(e.Y,_startPoint.Y);
_选择=新矩形(x1,y1,x2-x1,y2-y1);
}
}
///
///鼠标上的手柄向上
///
///args
MouseUp上的公共覆盖无效(MouseEventArgs e)
{
如果(基本启用)
{
如果(_selection.Width,则不能使用alpha通道,因为那样会使黄色褪色
我认为您必须走老路,为此使用WIN32 API:
[DllImport("gdi32.dll")]
static extern int SetROP2(IntPtr hdc, int fnDrawMode);
[DllImport("gdi32.dll")]
static extern IntPtr CreatePen(int fnPenStyle, int nWidth, uint crColor);
[DllImport("gdi32.dll")]
static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("gdi32.dll")]
static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
static extern bool MoveToEx(IntPtr hdc, int X, int Y, IntPtr lpPoint);
[DllImport("gdi32.dll")]
static extern bool LineTo(IntPtr hdc, int nXEnd, int nYEnd);
private const int PS_SOLID = 0;
private const int R2_MASKPEN = 9;
private const int R2_COPYPEN = 13;
Bitmap bmp = (Bitmap)Image.FromFile(@"c:\....png");
List<Point> points = new List<Point>();
结果是:
要直接在图像上而不是在控件的图形对象上绘制,需要进行更多的API调用:
[DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hdcDst, int x1, int y1, int cx, int cy,
IntPtr hdcSrc, int x2, int y2, int rop);
[DllImport("gdi32.dll")]
static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")]
static extern bool DeleteDC(IntPtr hdc);
private const int SRCCOPY = 0x00CC0020;
这是修改后的代码:
private void DrawHighlight(Point[] usePoints, int brushSize, Color brushColor) {
using (Graphics gBMP = Graphics.FromImage(bmp)) {
IntPtr hBMP = bmp.GetHbitmap();
IntPtr bDC = gBMP.GetHdc();
IntPtr mDC = CreateCompatibleDC(bDC);
IntPtr oDC = SelectObject(mDC, hBMP);
int useColor = System.Drawing.ColorTranslator.ToWin32(brushColor);
IntPtr pen = CreatePen(PS_SOLID, brushSize, (uint)useColor);
IntPtr xDC = SelectObject(mDC, pen);
SetROP2(mDC, R2_MASKPEN);
for (int i = 1; i <= usePoints.Length - 1; i++) {
Point p1 = usePoints[i - 1];
Point p2 = usePoints[i];
MoveToEx(mDC, p1.X, p1.Y, IntPtr.Zero);
LineTo(mDC, p2.X, p2.Y);
}
SetROP2(mDC, R2_COPYPEN);
BitBlt(bDC, 0, 0, bmp.Width, bmp.Height, mDC, 0, 0, SRCCOPY);
SelectObject(mDC, xDC);
DeleteObject(pen);
gBMP.ReleaseHdc(bDC);
SelectObject(mDC, oDC);
DeleteDC(mDC);
DeleteObject(hBMP);
}
}
private void DrawHighlight(点[]usePoints,int-brushSize,Color-brushColor){
使用(Graphics gBMP=Graphics.FromImage(bmp)){
IntPtr hBMP=bmp.GetHbitmap();
IntPtr bDC=gBMP.GetHdc();
IntPtr mDC=CreateCompatibleDC(bDC);
IntPtr oDC=选择对象(mDC、hBMP);
int useColor=System.Drawing.ColorTranslator.ToWin32(brushColor);
IntPtr pen=CreatePen(PS_实体,笔刷大小,(uint)使用颜色);
IntPtr xDC=选择对象(mDC、笔);
SetROP2(mDC,R2_MASKPEN);
对于(int i=1;我哇,谢谢,看起来它会起作用!我会尽快做一些更改,然后再联系你嗨,我有点进一步,但现在有另外两个问题,我喜欢你的徒手画想法,所以添加了一个形状枚举来绘制徒手画或矩形。我已经添加了一个更新的问题。你介意再看一看吗和我一起?我可以发送整个源代码,但我使用的是devexpress组件,所以不确定你是否有这些组件?@WraithNath我更新了帖子以在位图上绘制。太棒了!在徒手和矩形模式下都能正常工作。感谢你坚持使用此组件:)。如果你能推荐一些阅读资料,我不介意再学习一些dgi绘图?@LarsTech你能给我发邮件吗?我知道这是一个老帖子,但我想问你一些关于你发布的代码的问题。
protected override void OnMouseMove(MouseEventArgs e) {
base.OnMouseMove(e);
if (e.Button == MouseButtons.Left) {
points.Add(new Point(e.X, e.Y));
this.Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
e.Graphics.Clear(Color.White);
e.Graphics.DrawImage(bmp, Point.Empty);
DrawHighlight(e.Graphics, points.ToArray(), 16, Color.Yellow);
}
[DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hdcDst, int x1, int y1, int cx, int cy,
IntPtr hdcSrc, int x2, int y2, int rop);
[DllImport("gdi32.dll")]
static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")]
static extern bool DeleteDC(IntPtr hdc);
private const int SRCCOPY = 0x00CC0020;
private void DrawHighlight(Point[] usePoints, int brushSize, Color brushColor) {
using (Graphics gBMP = Graphics.FromImage(bmp)) {
IntPtr hBMP = bmp.GetHbitmap();
IntPtr bDC = gBMP.GetHdc();
IntPtr mDC = CreateCompatibleDC(bDC);
IntPtr oDC = SelectObject(mDC, hBMP);
int useColor = System.Drawing.ColorTranslator.ToWin32(brushColor);
IntPtr pen = CreatePen(PS_SOLID, brushSize, (uint)useColor);
IntPtr xDC = SelectObject(mDC, pen);
SetROP2(mDC, R2_MASKPEN);
for (int i = 1; i <= usePoints.Length - 1; i++) {
Point p1 = usePoints[i - 1];
Point p2 = usePoints[i];
MoveToEx(mDC, p1.X, p1.Y, IntPtr.Zero);
LineTo(mDC, p2.X, p2.Y);
}
SetROP2(mDC, R2_COPYPEN);
BitBlt(bDC, 0, 0, bmp.Width, bmp.Height, mDC, 0, 0, SRCCOPY);
SelectObject(mDC, xDC);
DeleteObject(pen);
gBMP.ReleaseHdc(bDC);
SelectObject(mDC, oDC);
DeleteDC(mDC);
DeleteObject(hBMP);
}
}