c# – 像剪切工具一样突出显示效果

前端之家收集整理的这篇文章主要介绍了c# – 像剪切工具一样突出显示效果前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在创建一个类似于 Windows 7剪切工具的新剪切工具.

但是我无法使高光效果起作用.

例如,剪切工具高亮显示如下:(突出显示在白色背景上非常明亮,看起来它没有透明度

我的剪切工具突出显示如下:

我确定使用的颜色是相同的(255,255,0),alpha通道为110.如果我降低透明度,那么它只是覆盖下面的文本.

我的剪辑是在白色顶部应用透明度,因为窗口剪切工具似乎更好地融合了它.

我在这做错了什么?

我用于突出显示注释的代码是:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Windows.Forms;
  7.  
  8. namespace Sicon.Snipper.Annotations
  9. {
  10. /// <summary>
  11. /// Highlight Annotation
  12. /// </summary>
  13. public class HighlightAnnotation : BaseAnnotation
  14. {
  15. #region Members
  16.  
  17. protected Rectangle _selection = Rectangle.Empty;
  18. protected const int _transparancyAlpha = 110;
  19. private Brush _brush;
  20.  
  21. #endregion Members
  22.  
  23. #region Properties
  24.  
  25. /// <summary>
  26. /// Gets or Sets the Brush
  27. /// </summary>
  28. protected Brush Brush
  29. {
  30. get { return _brush; }
  31. set { _brush = value; }
  32. }
  33.  
  34. /// <summary>
  35. /// Gets the Selection
  36. /// </summary>
  37. public Rectangle Selection
  38. {
  39. get { return _selection; }
  40. protected set { _selection = value; }
  41. }
  42.  
  43. #endregion Properties
  44.  
  45. #region Constructors
  46.  
  47. /// <summary>
  48. /// Constructor
  49. /// </summary>
  50. /// <param name="imageRef">Reference to the image</param>
  51. public HighlightAnnotation(Image imageRef,Control host)
  52. : base(imageRef,Pens.Yellow,host)
  53. {
  54. this.Brush = new SolidBrush(
  55. Color.FromArgb(
  56. _transparancyAlpha,this.Pen.Color));
  57. }
  58.  
  59. #endregion Constructors
  60.  
  61. #region Methods
  62.  
  63. /// <summary>
  64. /// Handles on Mouse down
  65. /// </summary>
  66. /// <param name="e">args</param>
  67. public override void OnMouseDown(MouseEventArgs e)
  68. {
  69. if (base.Enabled)
  70. {
  71. // Start the snip on mouse down
  72. if (e.Button != MouseButtons.Left) return;
  73. _startPoint = e.Location;
  74. _selection = new Rectangle(e.Location,new Size(0,0));
  75. }
  76. }
  77.  
  78. /// <summary>
  79. /// Handles Mouse Move
  80. /// </summary>
  81. /// <param name="e">args</param>
  82. public override void OnMouseMove(MouseEventArgs e)
  83. {
  84. if (base.Enabled)
  85. {
  86. // Modify the selection on mouse move
  87. if (e.Button != MouseButtons.Left) return;
  88. int x1 = Math.Min(e.X,_startPoint.X);
  89. int y1 = Math.Min(e.Y,_startPoint.Y);
  90. int x2 = Math.Max(e.X,_startPoint.X);
  91. int y2 = Math.Max(e.Y,_startPoint.Y);
  92. _selection = new Rectangle(x1,y1,x2 - x1,y2 - y1);
  93. }
  94. }
  95.  
  96. /// <summary>
  97. /// Handles on mouse up
  98. /// </summary>
  99. /// <param name="e">args</param>
  100. public override void OnMouseUp(MouseEventArgs e)
  101. {
  102. if (base.Enabled)
  103. {
  104. if (_selection.Width <= 0 || _selection.Height <= 0) return;
  105.  
  106. using (Graphics g = Graphics.FromImage(this.ImageRef))
  107. {
  108. Rectangle dest = new Rectangle(
  109. TranslateCenterImageMousePosition(_startPoint),_selection.Size);
  110.  
  111. g.FillRectangle(
  112. this.Brush,dest);
  113.  
  114. }
  115.  
  116. this.Enabled = false;
  117. }
  118. }
  119.  
  120. /// <summary>
  121. /// Hanles on paint
  122. /// </summary>
  123. /// <param name="g">graphics</param>
  124. public override void OnPaint(System.Drawing.Graphics g)
  125. {
  126. if (base.Enabled)
  127. g.FillRectangle(this.Brush,_selection);
  128. }
  129.  
  130. #endregion Methods
  131. }
  132. }

更新::

好吧,我做了一些改动,我也喜欢写意画的想法,但我做这个的主要原因是要有漂亮的整洁亮点等.

我现在的问题是,当我释放鼠标按钮时,矩形将被绘制为黑色,如下图所示.几乎就在那里!

GDI32.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6.  
  7. namespace Sicon.Snipper.Tools
  8. {
  9. public static class GDI32
  10. {
  11. [DllImport("gdi32.dll")]
  12. public static extern int SetROP2(IntPtr hdc,int fnDrawMode);
  13.  
  14. [DllImport("gdi32.dll")]
  15. public static extern IntPtr CreatePen(int fnPenStyle,int nWidth,uint crColor);
  16.  
  17. [DllImport("gdi32.dll")]
  18. public static extern IntPtr SelectObject(IntPtr hdc,IntPtr hgdiobj);
  19.  
  20. [DllImport("gdi32.dll")]
  21. public static extern bool DeleteObject(IntPtr hObject);
  22.  
  23. [DllImport("gdi32.dll")]
  24. public static extern bool MoveToEx(IntPtr hdc,int X,int Y,IntPtr lpPoint);
  25.  
  26. [DllImport("gdi32.dll")]
  27. public static extern bool LineTo(IntPtr hdc,int nXEnd,int nYEnd);
  28.  
  29. [DllImport("gdi32.dll")]
  30. public static extern bool Rectangle(IntPtr hdc,int nLeftRect,int nTopRect,int nRightRect,int nBottomRect);
  31. }
  32. }

新的Hightlight Annotation.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Windows.Forms;
  7. using Sicon.Snipper.Enums;
  8. using Sicon.Snipper.Tools;
  9.  
  10. namespace Sicon.Snipper.Annotations
  11. {
  12. /// <summary>
  13. /// Highlight Annotation
  14. /// </summary>
  15. public class HighlightAnnotation : BaseAnnotation
  16. {
  17. #region Members
  18.  
  19. protected Rectangle _selection = Rectangle.Empty;
  20. protected const int _transparancyAlpha = 110;
  21. private ShapeEnum _shape = ShapeEnum.Rectangle;
  22. List<Point> points = new List<Point>();
  23. private const int PS_SOLID = 0;
  24. private const int R2_MASKPEN = 9;
  25. private const int R2_COPYPEN = 13;
  26.  
  27. #endregion Members
  28.  
  29. #region Properties
  30.  
  31. /// <summary>
  32. /// Gets or Sets the Shape
  33. /// </summary>
  34. public ShapeEnum Shape
  35. {
  36. get { return _shape; }
  37. set { _shape = value; }
  38. }
  39.  
  40. /// <summary>
  41. /// Gets the Selection
  42. /// </summary>
  43. public Rectangle Selection
  44. {
  45. get { return _selection; }
  46. protected set { _selection = value; }
  47. }
  48.  
  49. #endregion Properties
  50.  
  51. #region Constructors
  52.  
  53. /// <summary>
  54. /// Constructor
  55. /// </summary>
  56. /// <param name="imageRef">Reference to the image</param>
  57. public HighlightAnnotation(Image imageRef,Control host,ShapeEnum shape)
  58. : base(imageRef,new Pen(Color.Yellow,16),host)
  59. {
  60. _shape = shape;
  61. }
  62.  
  63. #endregion Constructors
  64.  
  65. #region Methods
  66.  
  67. /// <summary>
  68. /// Handles on Mouse down
  69. /// </summary>
  70. /// <param name="e">args</param>
  71. public override void OnMouseDown(MouseEventArgs e)
  72. {
  73. if (base.Enabled)
  74. {
  75. // Start the snip on mouse down
  76. if (e.Button != MouseButtons.Left) return;
  77.  
  78. _startPoint = e.Location;
  79. _selection = new Rectangle(e.Location,0));
  80. }
  81. }
  82.  
  83. /// <summary>
  84. /// Handles Mouse Move
  85. /// </summary>
  86. /// <param name="e">args</param>
  87. public override void OnMouseMove(MouseEventArgs e)
  88. {
  89. if (base.Enabled)
  90. {
  91. // Modify the selection on mouse move
  92. if (e.Button != MouseButtons.Left) return;
  93.  
  94. //Add freehand points
  95. points.Add(new Point(e.X,e.Y));
  96.  
  97. //Update selection rectangele
  98. int x1 = Math.Min(e.X,_startPoint.X);
  99. int y1 = Math.Min(e.Y,_startPoint.Y);
  100. int x2 = Math.Max(e.X,_startPoint.X);
  101. int y2 = Math.Max(e.Y,_startPoint.Y);
  102. _selection = new Rectangle(x1,y2 - y1);
  103. }
  104. }
  105.  
  106. /// <summary>
  107. /// Handles on mouse up
  108. /// </summary>
  109. /// <param name="e">args</param>
  110. public override void OnMouseUp(MouseEventArgs e)
  111. {
  112. if (base.Enabled)
  113. {
  114. if (_selection.Width <= 0 || _selection.Height <= 0) return;
  115.  
  116. using (Graphics g = Graphics.FromImage(this.ImageRef))
  117. {
  118. switch (this.Shape)
  119. {
  120. case ShapeEnum.Freehand:
  121.  
  122. DrawHighlight(g,points.ToArray());
  123.  
  124. break;
  125.  
  126. case ShapeEnum.Rectangle:
  127.  
  128. Rectangle dest = new Rectangle(
  129. TranslateCenterImageMousePosition(_startPoint),_selection.Size);
  130.  
  131. DrawRectange(g);
  132.  
  133. break;
  134.  
  135. default: return;
  136. }
  137. }
  138.  
  139. this.Enabled = false;
  140. }
  141. }
  142.  
  143. /// <summary>
  144. /// Hanles on paint
  145. /// </summary>
  146. /// <param name="g">graphics</param>
  147. public override void OnPaint(System.Drawing.Graphics g)
  148. {
  149. if (base.Enabled)
  150. {
  151. switch (this.Shape)
  152. {
  153. case ShapeEnum.Freehand:
  154.  
  155. DrawHighlight(g,points.ToArray());
  156.  
  157. break;
  158.  
  159. case ShapeEnum.Rectangle:
  160.  
  161. DrawRectange(g);
  162.  
  163. break;
  164.  
  165. default: return;
  166. }
  167. }
  168. }
  169.  
  170. /// <summary>
  171. /// Draws a highlight
  172. /// </summary>
  173. /// <param name="g">graphics</param>
  174. /// <param name="usePoints">points to draw</param>
  175. private void DrawHighlight(Graphics g,Point[] usePoints)
  176. {
  177. int useColor = System.Drawing.ColorTranslator.ToWin32(base.Pen.Color);
  178. IntPtr pen = GDI32.CreatePen(PS_SOLID,(int)base.Pen.Width,(uint)useColor);
  179. IntPtr hDC = g.GetHdc();
  180. IntPtr xDC = GDI32.SelectObject(hDC,pen);
  181. GDI32.SetROP2(hDC,R2_MASKPEN);
  182. for (int i = 1; i <= usePoints.Length - 1; i++)
  183. {
  184. Point p1 = usePoints[i - 1];
  185. Point p2 = usePoints[i];
  186. GDI32.MoveToEx(hDC,p1.X,p1.Y,IntPtr.Zero);
  187. GDI32.LineTo(hDC,p2.X,p2.Y);
  188. }
  189. GDI32.SetROP2(hDC,R2_COPYPEN);
  190. GDI32.SelectObject(hDC,xDC);
  191. GDI32.DeleteObject(pen);
  192. g.ReleaseHdc(hDC);
  193. }
  194.  
  195. /// <summary>
  196. /// Draws a rectangle
  197. /// </summary>
  198. /// <param name="g">Graphics</param>
  199. private void DrawRectange(Graphics g)
  200. {
  201. Rectangle dest = new Rectangle(
  202. TranslateCenterImageMousePosition(_startPoint),_selection.Size);
  203.  
  204. int useColor = System.Drawing.ColorTranslator.ToWin32(base.Pen.Color);
  205. IntPtr pen = GDI32.CreatePen(PS_SOLID,R2_MASKPEN);
  206. GDI32.Rectangle(hDC,dest.Left,dest.Top,dest.Right,dest.Bottom);
  207. GDI32.SetROP2(hDC,xDC);
  208. GDI32.DeleteObject(pen);
  209. g.ReleaseHdc(hDC);
  210. }
  211.  
  212. #endregion Methods
  213. }
  214. }

解决方法

您不能使用Alpha通道,因为这会淡化黄色.

我认为你必须上学并使用WIN32 API:

  1. [DllImport("gdi32.dll")]
  2. static extern int SetROP2(IntPtr hdc,int fnDrawMode);
  3.  
  4. [DllImport("gdi32.dll")]
  5. static extern IntPtr CreatePen(int fnPenStyle,uint crColor);
  6.  
  7. [DllImport("gdi32.dll")]
  8. static extern IntPtr SelectObject(IntPtr hdc,IntPtr hgdiobj);
  9.  
  10. [DllImport("gdi32.dll")]
  11. static extern bool DeleteObject(IntPtr hObject);
  12.  
  13. [DllImport("gdi32.dll")]
  14. static extern bool MoveToEx(IntPtr hdc,IntPtr lpPoint);
  15.  
  16. [DllImport("gdi32.dll")]
  17. static extern bool LineTo(IntPtr hdc,int nYEnd);
  18.  
  19. private const int PS_SOLID = 0;
  20. private const int R2_MASKPEN = 9;
  21. private const int R2_COPYPEN = 13;
  22.  
  23. Bitmap bmp = (Bitmap)Image.FromFile(@"c:\....png");
  24. List<Point> points = new List<Point>();

这是我的亮点功能

  1. private void DrawHighlight(Graphics g,Point[] usePoints,int brushSize,Color brushColor) {
  2. int useColor = System.Drawing.ColorTranslator.ToWin32(brushColor);
  3. IntPtr pen = CreatePen(PS_SOLID,brushSize,(uint)useColor);
  4. IntPtr hDC = g.GetHdc();
  5. IntPtr xDC = SelectObject(hDC,pen);
  6. SetROP2(hDC,R2_MASKPEN);
  7. for (int i = 1; i <= usePoints.Length - 1; i++) {
  8. Point p1 = usePoints[i - 1];
  9. Point p2 = usePoints[i];
  10. MoveToEx(hDC,IntPtr.Zero);
  11. LineTo(hDC,p2.Y);
  12. }
  13. SetROP2(hDC,R2_COPYPEN);
  14. SelectObject(hDC,xDC);
  15. DeleteObject(pen);
  16. g.ReleaseHdc(hDC);
  17. }

我的测试代码

  1. protected override void OnMouseMove(MouseEventArgs e) {
  2. base.OnMouseMove(e);
  3. if (e.Button == MouseButtons.Left) {
  4. points.Add(new Point(e.X,e.Y));
  5. this.Invalidate();
  6. }
  7. }
  8.  
  9. protected override void OnPaint(PaintEventArgs e) {
  10. base.OnPaint(e);
  11. e.Graphics.Clear(Color.White);
  12. e.Graphics.DrawImage(bmp,Point.Empty);
  13. DrawHighlight(e.Graphics,points.ToArray(),16,Color.Yellow);
  14. }

结果:

要直接在图像上绘制而不是控件的Graphic对象,需要更多的API调用

  1. [DllImport("gdi32.dll")]
  2. public static extern bool BitBlt(IntPtr hdcDst,int x1,int y1,int cx,int cy,IntPtr hdcSrc,int x2,int y2,int rop);
  3.  
  4. [DllImport("gdi32.dll")]
  5. static extern IntPtr CreateCompatibleDC(IntPtr hdc);
  6.  
  7. [DllImport("gdi32.dll")]
  8. static extern bool DeleteDC(IntPtr hdc);
  9.  
  10. private const int SRCCOPY = 0x00CC0020;

这是修改后的代码

  1. private void DrawHighlight(Point[] usePoints,Color brushColor) {
  2. using (Graphics gBMP = Graphics.FromImage(bmp)) {
  3. IntPtr hBMP = bmp.GetHbitmap();
  4. IntPtr bDC = gBMP.GetHdc();
  5. IntPtr mDC = CreateCompatibleDC(bDC);
  6. IntPtr oDC = SelectObject(mDC,hBMP);
  7.  
  8. int useColor = System.Drawing.ColorTranslator.ToWin32(brushColor);
  9. IntPtr pen = CreatePen(PS_SOLID,(uint)useColor);
  10. IntPtr xDC = SelectObject(mDC,pen);
  11.  
  12. SetROP2(mDC,R2_MASKPEN);
  13. for (int i = 1; i <= usePoints.Length - 1; i++) {
  14. Point p1 = usePoints[i - 1];
  15. Point p2 = usePoints[i];
  16. MoveToEx(mDC,IntPtr.Zero);
  17. LineTo(mDC,p2.Y);
  18. }
  19. SetROP2(mDC,R2_COPYPEN);
  20.  
  21. BitBlt(bDC,bmp.Width,bmp.Height,mDC,SRCCOPY);
  22. SelectObject(mDC,xDC);
  23. DeleteObject(pen);
  24. gBMP.ReleaseHdc(bDC);
  25. SelectObject(mDC,oDC);
  26. DeleteDC(mDC);
  27. DeleteObject(hBMP);
  28. }
  29. }

猜你在找的C#相关文章