如何在canvas 上画没有锯齿的直线,有快速的反走样算法也好 ( 积分: 87 )

  • 主题发起人 主题发起人 yanggh
  • 开始时间 开始时间
Y

yanggh

Unregistered / Unconfirmed
GUEST, unregistred user!
我的程序需要实时显示路线(由直线段组成).在直线段斜率大,且长时,锯齿非常明显.如何才能快速消除这些锯齿,且不影响程序实时性.

如果使用OpenGl,若我的程序需要全部改写,那就惨了.没有时间了,上面催着交工.

恳求各位大侠出手相助,就剩下87分,穷囊而出了.
 
我的程序需要实时显示路线(由直线段组成).在直线段斜率大,且长时,锯齿非常明显.如何才能快速消除这些锯齿,且不影响程序实时性.

如果使用OpenGl,若我的程序需要全部改写,那就惨了.没有时间了,上面催着交工.

恳求各位大侠出手相助,就剩下87分,穷囊而出了.
 
使用GDI+,我也是新手,正在研究,相互学习:qq 22943752
 
给你点提示
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
procedure FastAntiAliasPicture(orig_bmp,big_bmp,out_bmp: TBitmap);
varconst
MaxPixelCount = 32768;

type
pRGBArray = ^TRGBArray;
TRGBArray = array[0..MaxPixelCount - 1] of TRGBTriple;

x, y, cx, cy: integer;
totr, totg, totb: integer;
Row1, Row2, Row3, DestRow: pRGBArray;
i: integer;
begin

for y := 0 to orig_bmp.Height - 1 do
begin
cy := y * 3;
Row1 := big_bmp.ScanLine[cy];
Row2 := big_bmp.ScanLine[cy + 1];
Row3 := big_bmp.ScanLine[cy + 2];
DestRow := out_bmp.ScanLine[y];
//扫描三行象素
for x := 0 to orig_bmp.Width - 1 do
begin
cx := 3 * x;
totr := 0;
totg := 0;
totb := 0;
for i := 0 to 2 do
begin
// 算出总的红色分量
totr := totr + Row1[cx + i].rgbtRed
+ Row2[cx + i].rgbtRed
+ Row3[cx + i].rgbtRed;
// 算出绿色分量
totg := totg + Row1[cx + i].rgbtGreen
+ Row2[cx + i].rgbtGreen
+ Row3[cx + i].rgbtGreen;
// 算出总的蓝色分量
totb := totb + Row1[cx + i].rgbtBlue
+ Row2[cx + i].rgbtBlue
+ Row3[cx + i].rgbtBlue;
end;
DestRow[x].rgbtRed := totr div 9;
// 取平均后的红色分量
DestRow[x].rgbtGreen := totg div 9;
// 取平均后的绿色分量
DestRow[x].rgbtBlue := totb div 9;
// 取平均后的蓝色分量
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
a,b,c:Tbitmap;


begin
a:=Tbitmap.Create;
b:=Tbitmap.Create;
c:=Tbitmap.Create;
a.PixelFormat:= pf24bit;
b.PixelFormat:= pf24bit;

c.PixelFormat:= pf24bit;
a.Height:=200;
a.Width:=200;
c.Height:=200;
c.Width:=200;
b.Height:=600;
b.Width:=600;
a.Canvas.Ellipse(10,10,140,180);
b.Canvas.Pen.Width:=3;
b.Canvas.Ellipse(10,10,140,180);

FastAntiAliasPicture(a,b,c);
canvas.Draw(0,0,c);
end;

end.
 
To ligen:
我看了大富翁以前的这方面帖子,没发现什么好办法。

这方面问题竟然这么难解决?
 
to 云影:
如上面这个例子,图像放大以后,反走样.
我试了,对程序的运行影响太大,CPU占用率太高,没有了实时性.

有别的更好的方法吗
 
这方面我做过一些测试的,按照你的需求,其实也只有使用GDI+, 不过GDI+的速度也比Windows本身的GraphAPI(就是Delphi本身的Canvas)要慢10倍以上, 我的建议:
1. 如果使用GDI+能完成(满足)你的需求就用GDI+;
2. 既然是动态的,也没有必要在乎锯齿问题,反正马上就过去了;
3. 如果只是为了美观, 你可以考虑使用简单的虚线(Delphi中的penStyle=psDot), 看起来效果会好一些;
4. 上面说的都不行,你就只好自己写类似GDI+中的高级画线例子了,但很难, 速度也不一定做得比GDI+快;
5. 祝福你!
 
to 天河流星;
谢谢你的指点.
这个程序,对速度要求很高.
在直线段斜率大且长时,锯齿太明显了.
一方面要求速度,另一方面希望锯齿小些.真的太难做到.
不知有没更好的办法?
 
现在的显卡不是自带硬件反锯齿功能,不知道怎么调用,如果有资料,能用上就太好了,
显卡公司的网站就是没有SDK之类下载。
 
难道没有人能解决这个问题吗?
卷起千堆雪大侠,你在哪里.
 
??没有人哪位富翁能解决这个问题,还是不愿出手相助?
 
rty56y56u6uy65u
 
请不要灌水,望各位大侠出手
 
一个象素,跟它左右的象素混合,如果上一个点比目前点偏左,那么修正上一个点,使它与右边混合时加重.
 
to 金卡绣球jk8.com;
如何混合,能否给点代码提示,谢谢!
 
混合,就是两个点的RGB单独加权平均啊,例如 50%,就 (左R+本R)/2

右边权重点,就 (本R + 右R*2)/3

类推,照画瓢 R G B 颜色.

“那么修正上一个点,使它与右边混合时加重. ”那么本点当然是『左加重了』
 
to 金卡绣球jk8.com:
按你的提示进行了像速混合,也就几行代码,

可惜这几行代码对程序的运行速度影响较大.
 
后退
顶部