哪位做过PS的索套工具? RT..程序中要用跟PS一样的索套工具,鼠标经过后,自动判断路径的闭合区域,然后再画蚂蚁线,再将选中区域的图像拷贝出来,蚂蚁线比较好画,关键是如何通过鼠标经过的点,获取这块闭合区域,其实也就是不规则形状... 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 可以根據螞蟻線顏色取得region 吧 花点时间帮你写了,主要是路径或者区域的操作... private FPoints: array of TPoint; FMouseDown: Boolean;...procedure TForm1.PaintBox1Paint(Sender: TObject);var Rgn: HRGN;begin with PaintBox1 do if Length(FPoints) > 0 then begin BeginPath(Canvas.Handle); Polyline(Canvas.Handle, FPoints[0], Length(FPoints)); EndPath(Canvas.Handle); //Rgn := PathToRegion(Canvas.Handle); if not FMouseDown then SelectClipPath(Canvas.Handle, RGN_COPY); Canvas.Draw(0, 0, Image1.Picture.Bitmap); Canvas.Pen.Style := psDot; StrokePath(Canvas.Handle); end else Canvas.Draw(0, 0, Image1.Picture.Bitmap);end;procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);begin SetLength(FPoints, 0); FMouseDown := True;end;procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);begin if ssLeft in Shift then begin SetLength(FPoints, Length(FPoints) + 1); FPoints[High(FPoints)] := Point(X, Y); Refresh; end;end;procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);begin FMouseDown := False; PaintBox1.Refresh;end;procedure TForm1.FormCreate(Sender: TObject);begin DoubleBuffered := True;end; 蚂蚁线是通过鼠标经过的点组成的区域来画的,不太明白你的意思。to:xiedewei 谢谢,不过不是我要的效果,你试一下PS的索套工具,要的就那效果 应该是用canny边缘算子,查找鼠标经过点处最近的边缘。 磁性套索工具一般情况下要复杂一些,简单的做法就是探索在当前指定半径范围内,对每个像素计算其和周围像素的差异,并统计出这个差异的最大值及其对应的坐标,如果这个差异大于你设定的容差,则把差异最大值对应的坐标加入到套索选区的数据结构中。//蚂蚁线比较好画 如果你说的蚂蚁线是指和PS一样的效果的话,这句话等你到你的选取比较复杂的时候你就不会这样说了。你会发现你的CPU使用率很高。如果你是参考codeproject上的marching ant的代码的话。 哦,只是简单的套索工具啊,那就一点难度也没有了啊,PS中是鼠标按下确定一个顶点,哪个橡皮擦效果更不是难题了, 至于你要复制选中的图像,可以利用GDI的裁剪区域的概念,或者GDI+的。 如果要抗锯齿的话,那就要复杂一些了。 Public Declare Function CreatePolygonRgn Lib "gdi32" Alias "CreatePolygonRgn" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As LongnPolyFillMode 这个东西会帮助你。 to : laviewpbt谢谢,现在有一个问题,就是在 beginpath -> 画形状 -> endpath 之后,再通过FlattenPath 函数路径中的所有曲线都转换成线段,最后再用 GetPath 获取路径中的点时,如果是在鼠标事件中(down,move,up等)执行这段代码,则返回的一直是-1,取不到任何点,如果在一个按钮单击事件中执行,就可以正常获取得到路径中的所有点,真搞不懂,怎么会这样? http://www.bestsales4u.com我是电脑菜鸟,请多多指教! 可以找一下开源的paint.net来看一下里面是怎么实现的,它里面写的有这样的功能 逛CSDN5年多了,说实在的没看到多少图形或者图像学高手,也许是高手一般都不愿意回答问题吧。楼主呢,我自认为在图像编辑方面有一定的造诣了,关于你这个问题我不清楚你要做到的深度,先假定你要做到类似PS的深度,那么你需要具有以下的能力。1、选区,什么是选区,选区就是一副8位灰度图,就是一个mask,选中的部分值为255,未选中的部分为0,值为0到255之间表示部分选中,大家看到的蚂蚁线实际上是选区中大于127的部分,只是选区的一种外在表达方式。2、选区为什么可以移动:移动选区其实就是改变选区相对于画布的位置,并没有改变选区的数据。3、套索工具就是把用户所选择的多边形范围的灰度图的值修改为选中。 chdjicha zc z vHOSc ac c 谢谢,看来我得先熟悉一下PS的原理了,说实在的,看不出来PS是你所说的那种方式做的,我水平很有限,别见笑了.. PHOTOSHOP用得不多, 记忆中索套应该和魔术棒是差不多的功能.边缘判断是一个比较复杂的问题, 基于灰度或色相的判断是比较常见的做法, 在某些主体明显的图样上可以得到很好的效果.中间还会涉及到一些数据处理技巧方面的问题, 比如路径点的重复判断, 同方向路径点压缩等. 可以极大的降低路径点的数量, 这点在创建多边形的时候会极大得提高效率, 以前作过一个类似魔术棒功能的测试下得到自动边缘检测得到的多边形定点数在加入同方向路径点压缩之后,定点数量至少可以降低一个数量级.我设想中的"磁性"索套功能应该是:某一路径点沿着其前一点后后一点的连线的垂直方向在一定范围内分别计算该方向上像素的灰度或色差值,自动选取差值最大的点作为新点. 说是设想是因为我并没有在自己的程序中实现这个功能.关于对选中区域图像的复制和移动楼主可以请教laviewpbt,他的程序已经有这个功能了. 楼主可以看看Paint.NET的代码,应该有相关代码... 昨天看岔眼了,以为是C#的。今天仔细看原来是delphi的。苍天呐,delphi已经堕落到这种地步了么?牛人呢?牛人们都上哪去了? 请教一个关于Listview重新排出序号的方法 如何用fast report做本页合计 值为前几页的小计的和 啊 帮忙啊 简单的取字符串问题 动态释放ODAC组件时 invalid pointer operation 请问如何得到汉字的gb2312编码的十六进制表示?在线等。。。 问个菜菜的问题 我用sqlserver2k的企业管理器中重新建立用户的问题! 一个简单的问题,Delphi我不太熟,各位帮看看 怎样得到任意字体的不同字符宽度---请教~~~~~~~~~折磨我好久了 如何在MDI主窗体中访问由DLL创建的MDI子窗体? 有没有用于Unicode字符串的POS函数? 关于时间
private
FPoints: array of TPoint;
FMouseDown: Boolean;
...
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
Rgn: HRGN;
begin
with PaintBox1 do
if Length(FPoints) > 0 then
begin
BeginPath(Canvas.Handle);
Polyline(Canvas.Handle, FPoints[0], Length(FPoints));
EndPath(Canvas.Handle);
//Rgn := PathToRegion(Canvas.Handle);
if not FMouseDown then
SelectClipPath(Canvas.Handle, RGN_COPY);
Canvas.Draw(0, 0, Image1.Picture.Bitmap);
Canvas.Pen.Style := psDot;
StrokePath(Canvas.Handle);
end
else
Canvas.Draw(0, 0, Image1.Picture.Bitmap);
end;procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
SetLength(FPoints, 0);
FMouseDown := True;
end;procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if ssLeft in Shift then
begin
SetLength(FPoints, Length(FPoints) + 1);
FPoints[High(FPoints)] := Point(X, Y);
Refresh;
end;
end;procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FMouseDown := False;
PaintBox1.Refresh;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
DoubleBuffered := True;
end;
to:xiedewei
谢谢,不过不是我要的效果,你试一下PS的索套工具,要的就那效果
如果你说的蚂蚁线是指和PS一样的效果的话,这句话等你到你的选取比较复杂的时候你就不会这样说了。
你会发现你的CPU使用率很高。如果你是参考codeproject上的marching ant的代码的话。
nPolyFillMode 这个东西会帮助你。
谢谢,现在有一个问题,就是在 beginpath -> 画形状 -> endpath 之后,再通过FlattenPath 函数路径中的所有曲线都转换成线段,最后再用 GetPath 获取路径中的点时,如果是在鼠标事件中(down,move,up等)执行这段代码,则返回的一直是-1,取不到任何点,如果在一个按钮单击事件中执行,就可以正常获取得到路径中的所有点,真搞不懂,怎么会这样?
我是电脑菜鸟,请多多指教!
边缘判断是一个比较复杂的问题, 基于灰度或色相的判断是比较常见的做法, 在某些主体明显的图样上可以得到很好的效果.
中间还会涉及到一些数据处理技巧方面的问题, 比如路径点的重复判断, 同方向路径点压缩等. 可以极大的降低路径点的数量, 这点在创建多边形的时候会极大得提高效率, 以前作过一个类似魔术棒功能的测试下得到自动边缘检测得到的多边形定点数在加入同方向路径点压缩之后,定点数量至少可以降低一个数量级.我设想中的"磁性"索套功能应该是:某一路径点沿着其前一点后后一点的连线的垂直方向在一定范围内分别计算该方向上像素的灰度或色差值,自动选取差值最大的点作为新点. 说是设想是因为我并没有在自己的程序中实现这个功能.关于对选中区域图像的复制和移动楼主可以请教laviewpbt,他的程序已经有这个功能了.
苍天呐,delphi已经堕落到这种地步了么?牛人呢?牛人们都上哪去了?