GDI/GDI+如何实现文字描边效果

时间:2022-01-03 23:47:25
Graphics g = e.Graphics;
            g.Clear(Color.Blue);
            GraphicsPath myPath = new GraphicsPath();

            // Set up all the string parameters.
            string stringText = "测试文字觉得对方";
            FontFamily family = new FontFamily("宋体");
            int fontStyle = (int)FontStyle.Bold;
            int emSize = 20;
            Point origin = new Point(20, 20);
            StringFormat format = StringFormat.GenericDefault;

            // Add the string to the path.
            myPath.AddString(stringText,
                family,
                0,
                emSize,
                origin,
                format);

            //Draw the path to the screen.
            e.Graphics.FillPath(Brushes.Black, myPath);
            e.Graphics.DrawPath(new Pen(Color.White), myPath);

这种方法效果很差,需要实现像Winamp V5.54版本的漂浮歌词文字效果(这里图片上传有错误),描边无锯齿。

8 个解决方案

#1


没搞过.

关注一下~`

#2


Graphics g = e.Graphics;
             g.SmoothingMode = SmoothingMode.AntiAlias;

加上红色的的那一句就可以了

#3


以前作GDI没碰到过这个功能要求,还真不知道有这样的功能,不过测试了一下代码,确实好功能,很好很强大。

#4


引用 2 楼 dunao 的回复:
Graphics g = e.Graphics; 
            g.SmoothingMode = SmoothingMode.AntiAlias; 

加上红色的的那一句就可以了


支持!

#5


引用 4 楼 nattystyle 的回复:
引用 2 楼 dunao 的回复:
Graphics g = e.Graphics; 
            g.SmoothingMode = SmoothingMode.AntiAlias; 

加上红色的的那一句就可以了 
 

支持!
.

#6


引用 2 楼 dunao 的回复:
Graphics g = e.Graphics; 
            g.SmoothingMode = SmoothingMode.AntiAlias; 

加上红色的的那一句就可以了


效果的确有改善,不过仍然称不上理想。

经过放大Photoshop的描边效果,发现其是对文本像素的上、下、左、右、左上、左下、右上、右下八个像素(当然要判断,并不是这些像素都需要着色)进行着色,前四个像素颜色比后四个像素深(大家自己去开Photoshop测试观察)。

刚开始我没对后四个像素着色,感觉有锯齿,着色后效果好多了,和ps的一模一样

测试的Delphi代码如下(尚未优化,效率不高):



const
BACKCOLOR   = clWhite;
TEXTCOLOR   : TRGB=(R:255; G:0;   B:0);
BORDERCOLOR  = $00572225;
BORDERCOLOR2 = clBlack;
NONEPOINT : TPoint=(X:-1; Y:-1);

var
P1,P2   : PRGB;
pRGBArr : array of PRGB;
BlockRGB: array[0..3] of TRGB;
Bmp, Bmp2  : TBitmap;
i,j     : integer;
x, y    : integer;
flag    : Boolean;
AFile   : TextFile;
str     : string;
begin
   Bmp  := TBitmap.Create;
   Bmp2 := TBitmap.Create;
   Bmp.LoadFromFile('e:\text.bmp');
   Bmp2.LoadFromFile('e:\text.bmp');

   x:=0;
   y:=0;
   for x:=0 to Bmp.Width-1 do
    for y:=0 to Bmp.Height-1 do
      with Bmp.Canvas do
       begin
         if Pixels[x,y]<>BACKCOLOR then
            begin
               if (y>0) and (Pixels[x,y-1]=BACKCOLOR) then
                  Bmp2.Canvas.Pixels[x,y-1] := BORDERCOLOR;
               if Pixels[x,y+1]=BACKCOLOR then
                  Bmp2.Canvas.Pixels[x,y+1] := BORDERCOLOR;
               if (x>0) and (Pixels[x-1,y]=BACKCOLOR) then
                  Bmp2.Canvas.Pixels[x-1,y] := BORDERCOLOR;
               if Pixels[x+1, y] = BACKCOLOR then
                  Bmp2.Canvas.Pixels[x+1,y] := BORDERCOLOR;

               if (y>0) and (x>0) and (Pixels[x-1,y-1]=BACKCOLOR) then //左上角
                  Bmp2.Canvas.Pixels[x-1,y-1] := BORDERCOLOR2;
               if (y>0) and (Pixels[x+1,y-1]=BACKCOLOR) then //右上角
                  Bmp2.Canvas.Pixels[x+1,y-1] := BORDERCOLOR2;
               if (x>0) and (Pixels[x-1, y+1]=BACKCOLOR) then
                  Bmp2.Canvas.Pixels[x-1, y+1] := BORDERCOLOR2; //左下角
               if (Pixels[x+1, y+1]=BACKCOLOR) then
                  Bmp2.Canvas.Pixels[x+1, y+1] := BORDERCOLOR2; //右下角

            end;
       end;

   BitBlt(Canvas.Handle,10,10,Bmp.Width,BMp.Height,Bmp2.Canvas.Handle,0,0, SRCCOPY);
   //TransparentBlt(Canvas.Handle,10,50,Bmp.Width,BMp.Height,Bmp2.Canvas.Handle,0,0, Bmp.Width, Bmp.Height, clWhite);
   Bmp.Free;
   Bmp2.Free;


(ps :csdn的图片上传功能不行!)

#7


可惜只能使用一种FontStyle。非常遗憾

#8


学习了

#1


没搞过.

关注一下~`

#2


Graphics g = e.Graphics;
             g.SmoothingMode = SmoothingMode.AntiAlias;

加上红色的的那一句就可以了

#3


以前作GDI没碰到过这个功能要求,还真不知道有这样的功能,不过测试了一下代码,确实好功能,很好很强大。

#4


引用 2 楼 dunao 的回复:
Graphics g = e.Graphics; 
            g.SmoothingMode = SmoothingMode.AntiAlias; 

加上红色的的那一句就可以了


支持!

#5


引用 4 楼 nattystyle 的回复:
引用 2 楼 dunao 的回复:
Graphics g = e.Graphics; 
            g.SmoothingMode = SmoothingMode.AntiAlias; 

加上红色的的那一句就可以了 
 

支持!
.

#6


引用 2 楼 dunao 的回复:
Graphics g = e.Graphics; 
            g.SmoothingMode = SmoothingMode.AntiAlias; 

加上红色的的那一句就可以了


效果的确有改善,不过仍然称不上理想。

经过放大Photoshop的描边效果,发现其是对文本像素的上、下、左、右、左上、左下、右上、右下八个像素(当然要判断,并不是这些像素都需要着色)进行着色,前四个像素颜色比后四个像素深(大家自己去开Photoshop测试观察)。

刚开始我没对后四个像素着色,感觉有锯齿,着色后效果好多了,和ps的一模一样

测试的Delphi代码如下(尚未优化,效率不高):



const
BACKCOLOR   = clWhite;
TEXTCOLOR   : TRGB=(R:255; G:0;   B:0);
BORDERCOLOR  = $00572225;
BORDERCOLOR2 = clBlack;
NONEPOINT : TPoint=(X:-1; Y:-1);

var
P1,P2   : PRGB;
pRGBArr : array of PRGB;
BlockRGB: array[0..3] of TRGB;
Bmp, Bmp2  : TBitmap;
i,j     : integer;
x, y    : integer;
flag    : Boolean;
AFile   : TextFile;
str     : string;
begin
   Bmp  := TBitmap.Create;
   Bmp2 := TBitmap.Create;
   Bmp.LoadFromFile('e:\text.bmp');
   Bmp2.LoadFromFile('e:\text.bmp');

   x:=0;
   y:=0;
   for x:=0 to Bmp.Width-1 do
    for y:=0 to Bmp.Height-1 do
      with Bmp.Canvas do
       begin
         if Pixels[x,y]<>BACKCOLOR then
            begin
               if (y>0) and (Pixels[x,y-1]=BACKCOLOR) then
                  Bmp2.Canvas.Pixels[x,y-1] := BORDERCOLOR;
               if Pixels[x,y+1]=BACKCOLOR then
                  Bmp2.Canvas.Pixels[x,y+1] := BORDERCOLOR;
               if (x>0) and (Pixels[x-1,y]=BACKCOLOR) then
                  Bmp2.Canvas.Pixels[x-1,y] := BORDERCOLOR;
               if Pixels[x+1, y] = BACKCOLOR then
                  Bmp2.Canvas.Pixels[x+1,y] := BORDERCOLOR;

               if (y>0) and (x>0) and (Pixels[x-1,y-1]=BACKCOLOR) then //左上角
                  Bmp2.Canvas.Pixels[x-1,y-1] := BORDERCOLOR2;
               if (y>0) and (Pixels[x+1,y-1]=BACKCOLOR) then //右上角
                  Bmp2.Canvas.Pixels[x+1,y-1] := BORDERCOLOR2;
               if (x>0) and (Pixels[x-1, y+1]=BACKCOLOR) then
                  Bmp2.Canvas.Pixels[x-1, y+1] := BORDERCOLOR2; //左下角
               if (Pixels[x+1, y+1]=BACKCOLOR) then
                  Bmp2.Canvas.Pixels[x+1, y+1] := BORDERCOLOR2; //右下角

            end;
       end;

   BitBlt(Canvas.Handle,10,10,Bmp.Width,BMp.Height,Bmp2.Canvas.Handle,0,0, SRCCOPY);
   //TransparentBlt(Canvas.Handle,10,50,Bmp.Width,BMp.Height,Bmp2.Canvas.Handle,0,0, Bmp.Width, Bmp.Height, clWhite);
   Bmp.Free;
   Bmp2.Free;


(ps :csdn的图片上传功能不行!)

#7


可惜只能使用一种FontStyle。非常遗憾

#8


学习了