在c#中,使用system.drawing命名空间可以简单处理位图,实现取色和绘图。以下是核心操作的代码示例。
1. 提取鼠标指定点的颜色值
要获取屏幕上任意一点的颜色,核心是使用graphics.copyfromscreen方法截取屏幕,然后从截取的位图中读取像素颜色 。
using system;
using system.drawing;
using system.runtime.interopservices;
using system.windows.forms;
public class colorpicker
{
// 方法一:通过截屏获取指定屏幕坐标的颜色(推荐,更通用)
public static color getcoloratscreenpoint(point screenpoint)
{
// 创建一个1x1像素的位图
using (bitmap bitmap = new bitmap(1, 1))
{
// 使用graphics对象从屏幕指定位置拷贝1个像素 using (graphics g = graphics.fromimage(bitmap))
{
g.copyfromscreen(screenpoint, point.empty, new size(1, 1));
}
// 返回该像素的颜色
return bitmap.getpixel(0, 0);
}
}
// 方法二:使用windows api (getpixel) 直接获取(需要引用user32.dll和gdi32.dll)
[dllimport("user32.dll")]
private static extern intptr getdc(intptr hwnd);
[dllimport("user32.dll")]
private static extern int releasedc(intptr hwnd, intptr hdc);
[dllimport("gdi32.dll")]
private static extern uint getpixel(intptr hdc, int nxpos, int nypos);
public static color getcoloratscreenpoint_api(point screenpoint)
{
intptr hdc = getdc(intptr.zero);
uint pixel = getpixel(hdc, screenpoint.x, screenpoint.y);
releasedc(intptr.zero, hdc);
// 将getpixel返回的colorref转换为color对象 byte red = (byte)(pixel & 0x000000ff);
byte green = (byte)((pixel & 0x0000ff00) >> 8);
byte blue = (byte)((pixel & 0x00ff0000) >> 16);
return color.fromargb(red, green, blue);
}
// 示例:在定时器或循环中实时获取鼠标位置颜色 public static void startrealtimecolorpick(label colorlabel)
{
timer timer = new timer();
timer.interval = 50; // 每50毫秒更新一次
timer.tick += (sender, e) =>
{
point mousepos = control.mouseposition;
color color = getcoloratscreenpoint(mousepos);
colorlabel.text = $"坐标:({mousepos.x},{mousepos.y}), rgb:({color.r},{color.g},{color.b})";
colorlabel.backcolor = color;
};
timer.start();
}
}2. 在位图上画圆
在位图上绘图,需要使用graphics对象,并调用其绘图方法 。
using system.drawing;
using system.drawing.drawing2d;
public class bitmapdrawer
{
// 方法:在现有位图上绘制一个圆
public static bitmap drawcircleonbitmap(bitmap originalbitmap, point center, int radius, color circlecolor, int penwidth = 2)
{
// 创建原图的副本,避免修改原图 bitmap resultbitmap = new bitmap(originalbitmap);
using (graphics g = graphics.fromimage(resultbitmap))
{
// 设置绘图质量
g.smoothingmode = smoothingmode.antialias;
g.interpolationmode = interpolationmode.highqualitybicubic;
// 创建画笔
using (pen pen = new pen(circlecolor, penwidth))
{
// 计算圆的左上角坐标和直径 rectangle rect = new rectangle(center.x - radius, center.y - radius, radius * 2, radius * 2);
// 绘制圆 g.drawellipse(pen, rect);
// 如果需要填充圆,使用 brush
// using (solidbrush brush = new solidbrush(color.fromargb(50, circlecolor)))
// {
// g.fillellipse(brush, rect);
// }
}
}
return resultbitmap;
}
// 方法:创建一个新的位图并在上面画圆
public static bitmap createbitmapwithcircle(int width, int height, point center, int radius, color backgroundcolor, color circlecolor)
{
bitmap bitmap = new bitmap(width, height);
using (graphics g = graphics.fromimage(bitmap))
{
// 填充背景色 using (solidbrush backgroundbrush = new solidbrush(backgroundcolor))
{
g.fillrectangle(backgroundbrush, 0, 0, width, height);
}
// 画圆
using (pen pen = new pen(circlecolor, 3))
{
rectangle rect = new rectangle(center.x - radius, center.y - radius, radius * 2, radius * 2);
g.drawellipse(pen, rect);
}
}
return bitmap;
}
}
3. 结合鼠标交互:点击取色并画圆
以下是一个完整的windows forms示例,实现点击图片框(picturebox)获取该点颜色,并以该点为中心画圆。
using system;
using system.drawing;
using system.windows.forms;
namespace bitmapsimpledemo
{
public partial class mainform : form
{
private bitmap originalbitmap; // 原始位图 private bitmap displayedbitmap; // 当前显示的位图(可能已画圆)
private point lastclickpoint;
private int circleradius = 30;
public mainform()
{
initializecomponent();
// 加载一张示例图片到picturebox
originalbitmap = new bitmap(@"你的图片路径.jpg");
picturebox1.image = originalbitmap;
displayedbitmap = (bitmap)originalbitmap.clone();
}
// picturebox的鼠标点击事件 private void picturebox1_mouseclick(object sender, mouseeventargs e)
{
if (originalbitmap == null) return;
lastclickpoint = e.location;
// 1. 获取点击位置的颜色
color clickedcolor = originalbitmap.getpixel(e.x, e.y);
lblcolorinfo.text = $"点击点颜色 - r:{clickedcolor.r} g:{clickedcolor.g} b:{clickedcolor.b}";
pnlcolorpreview.backcolor = clickedcolor;
// 2. 在 displayedbitmap 上以点击点为中心画圆
// 先重置为原图
displayedbitmap?.dispose();
displayedbitmap = (bitmap)originalbitmap.clone();
using (graphics g = graphics.fromimage(displayedbitmap))
{
g.smoothingmode = system.drawing.drawing2d.smoothingmode.antialias;
// 使用与取色形成对比的颜色画圆,例如取反色 color drawcolor = color.fromargb(255 - clickedcolor.r, 255 - clickedcolor.g, 255 - clickedcolor.b);
using (pen pen = new pen(drawcolor, 3))
{
rectangle rect = new rectangle(e.x - circleradius, e.y - circleradius, circleradius * 2, circleradius * 2);
g.drawellipse(pen, rect);
}
}
// 3. 更新picturebox显示 picturebox1.image = displayedbitmap;
}
// 按钮:保存画了圆的图片 private void btnsave_click(object sender, eventargs e)
{
if (displayedbitmap != null)
{
savefiledialog sfd = new savefiledialog();
sfd.filter = "png image|*.png|jpeg image|*.jpg";
if (sfd.showdialog() == dialogresult.ok)
{
displayedbitmap.save(sfd.filename);
}
}
}
// 按钮:重置图片,清除所有圆圈 private void btnreset_click(object sender, eventargs e)
{
displayedbitmap?.dispose();
displayedbitmap = (bitmap)originalbitmap.clone();
picturebox1.image = displayedbitmap;
lblcolorinfo.text = "颜色信息";
pnlcolorpreview.backcolor = systemcolors.control;
}
// 窗体关闭时释放资源
private void mainform_formclosing(object sender, formclosingeventargs e)
{
originalbitmap?.dispose();
displayedbitmap?.dispose();
}
}
}
关键操作总结:
| 任务 | 核心类/方法 | 说明 |
|---|---|---|
| 获取屏幕坐标颜色 | graphics.copyfromscreen | 通过截取1像素屏幕区域实现,无需api声明,更安全 。 |
| 获取位图像素颜色 | bitmap.getpixel(x, y) | 直接从bitmap对象中读取指定坐标的颜色。 |
| 在位图上绘图 | graphics.fromimage(bitmap) | 从位图创建graphics画布,然后使用drawellipse画圆 。 |
| 鼠标交互取色 | picturebox.mouseclick事件 + e.location | 在控件内获取鼠标相对坐标,再对应到位图像素。 |
| 资源管理 | using语句或手动dispose() | bitmap和graphics是非托管资源,使用后必须释放。 |
到此这篇关于c#使用system.drawing实现位图取色与绘图的方法的文章就介绍到这了,更多相关c#位图取色与绘图内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论