最近在研究文字水印,因为要实现透明度,并且实现文字精细,所以先在一个画板上画出来了这个文字,再把它和原来的图片进行Alpha融合,但是因为文字精细的时候,它的周围的一些颜色就不会等于我预设地透明色,这时候融合后的字周围就会有白色(我设的透明色)的一些残余,感觉好影响效果呀,不知道大家作这样的东西的时候,是怎么实现的?

解决方案 »

  1.   

    constantine(飘遥的安吉儿) 说的对,数字水印技术不是这样的,这是听我一个念数学的朋友说的!
    加水印与提水印都要通过软件来实现,用来防伪,防复制,保护版权的,算法挺复杂的.
    你有这方面的资料可以提供给我吗,一起研究一下吧!
      

  2.   

    我也不想这样说,只是大家都是这么叫.
    我要的是图片的Alpha融合,有没有人能够帮我?
      

  3.   

    很简单,在32位色图像的基础上来实现Alpha混合。这样就有了0-255的梯度。你那所谓的透明色其实也就是等同于另外记录了Alpha值,只不过只有0和255两种选择。
      

  4.   

    不要用半透明,要用混合算法;具体可以看我刚写的例子;放3个image, 分别为image1,src,dest ,src保存的图象要比dest小点,因为没有做范围判断,会画到dest上,dest则会从image1取一个背景.unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls;type
      TForm1 = class(TForm)
        src: TImage;
        dest: TImage;
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        Button4: TButton;
        Image1: TImage;
        Button5: TButton;
        procedure Button3Click(Sender: TObject);
        procedure Button5Click(Sender: TObject);
        procedure Button4Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1             : TForm1;implementation
    uses Math;{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);    //图像混合Additive-Blending
    var
      x1, y1            : integer;
      P1, p2            : pbyteArray;
    begin
      src.Picture.Bitmap.PixelFormat := pf24bit;
      dest.Picture.Bitmap.PixelFormat := pf24bit;  for y1 := 0 to src.Picture.Bitmap.Height - 1 do
      begin
        p1 := dest.Picture.Bitmap.ScanLine[y1];
        p2 := src.Picture.Bitmap.ScanLine[y1];
        for x1 := 0 to src.Picture.Bitmap.Width - 1 do
        begin
          //      p[x * 3] := b;                    //蓝b
          //      P[x * 3 + 1] := g;                //绿g
          //      P[x * 3 + 2] := r;                //红r      //不是黑色则进行处理,因为黑色要作为透明色
          if (p2[x1 * 3] <> 0) or (p2[x1 * 3 + 1] = 0) or (p2[x1 * 3 + 2] = 0) then
          begin
            p1[x1 * 3] := Min(255, p1[x1 * 3] + p2[x1 * 3]);
            p1[x1 * 3 + 1] := Min(255, p1[x1 * 3 + 1] + p2[x1 * 3 + 1]);
            p1[x1 * 3 + 2] := Min(255, p1[x1 * 3 + 2] + p2[x1 * 3 + 2]);
          end;    end;
      end;end;procedure TForm1.Button2Click(Sender: TObject);   //半透明
    var
      x1, y1            : integer;
      P1, p2            : pbyteArray;
    begin
      src.Picture.Bitmap.PixelFormat := pf24bit;
      dest.Picture.Bitmap.PixelFormat := pf24bit;  for y1 := 0 to src.Picture.Bitmap.Height - 1 do
      begin
        p1 := dest.Picture.Bitmap.ScanLine[y1];
        p2 := src.Picture.Bitmap.ScanLine[y1];
        for x1 := 0 to src.Picture.Bitmap.Width - 1 do
        begin
          //      p[x * 3] := b;                    //蓝b
          //      P[x * 3 + 1] := g;                //绿g
          //      P[x * 3 + 2] := r;                //红r
          (*
          r,g,b 为最后取得的颜色值;r1,g1,b1是上层的颜色值;r2,g2,b2是下层颜色值
          r = r1/2 + r2/2;
          g = g1/2 + g2/2;
          b = b1/2 + b2/2;
          以上为50%透明。若要使用不同的透明度用以下算法(ALPHA=透明度):
          (50%以下)
          r = r1 - r1/ALPHA + r2/ALPHA;
          g = g1 - g1/ALPHA + g2/ALPHA;
          b = b1 - b1/ALPHA + b2/ALPHA;
          (50%以上)
          r = r1/ALPHA + r2 - r2/ALPHA;
          g = g1/ALPHA + g2 - g2/ALPHA;
          b = b1/ALPHA + b2 - b2/ALPHA;
          *)
          //不是黑色则进行处理,因为黑色要作为透明色
          if (p2[x1 * 3] <> 0) or (p2[x1 * 3 + 1] = 0) or (p2[x1 * 3 + 2] = 0) then
          begin
            //50%
            p1[x1 * 3] := Min(255, (p1[x1 * 3] div 2) + (p2[x1 * 3] div 2));
            p1[x1 * 3 + 1] := Min(255, (p1[x1 * 3 + 1] div 2) + (p2[x1 * 3 + 1] div
              2));
            p1[x1 * 3 + 2] := Min(255, (p1[x1 * 3 + 2] div 2) + (p2[x1 * 3 + 2] div
              2));
          end;    end;
      end;
    end;procedure TForm1.Button4Click(Sender: TObject);      //图像混合Subtractive-Blending
    var
      x1, y1            : integer;
      P1, p2            : pbyteArray;
    begin
      src.Picture.Bitmap.PixelFormat := pf24bit;
      dest.Picture.Bitmap.PixelFormat := pf24bit;  for y1 := 0 to src.Picture.Bitmap.Height - 1 do
      begin
        p1 := dest.Picture.Bitmap.ScanLine[y1];
        p2 := src.Picture.Bitmap.ScanLine[y1];
        for x1 := 0 to src.Picture.Bitmap.Width - 1 do
        begin
          //      p[x * 3] := b;                    //蓝b
          //      P[x * 3 + 1] := g;                //绿g
          //      P[x * 3 + 2] := r;                //红r      //不是黑色则进行处理,因为黑色要作为透明色
          if (p2[x1 * 3] <> 0) or (p2[x1 * 3 + 1] = 0) or (p2[x1 * 3 + 2] = 0) then
          begin
            p1[x1 * 3] := Max(0, p1[x1 * 3] - p2[x1 * 3]);
            p1[x1 * 3 + 1] := Max(0, p1[x1 * 3 + 1] - p2[x1 * 3 + 1]);
            p1[x1 * 3 + 2] := Max(0, p1[x1 * 3 + 2] - p2[x1 * 3 + 2]);
          end;    end;
      end;
    end;procedure TForm1.Button5Click(Sender: TObject);
    begin
      dest.Picture.Graphic.Assign(image1.Picture.Graphic);
    end;procedure TForm1.Button3Click(Sender: TObject);    //混合+透明
    var
      x1, y1            : integer;
      P1, p2            : pbyteArray;
    begin
      src.Picture.Bitmap.PixelFormat := pf24bit;
      dest.Picture.Bitmap.PixelFormat := pf24bit;  for y1 := 0 to src.Picture.Bitmap.Height - 1 do
      begin
        p1 := dest.Picture.Bitmap.ScanLine[y1];
        p2 := src.Picture.Bitmap.ScanLine[y1];
        for x1 := 0 to src.Picture.Bitmap.Width - 1 do
        begin
          //      p[x * 3] := b;                    //蓝b
          //      P[x * 3 + 1] := g;                //绿g
          //      P[x * 3 + 2] := r;                //红r      //不是黑色则进行处理,因为黑色要作为透明色
          if (p2[x1 * 3] <> 0) or (p2[x1 * 3 + 1] = 0) or (p2[x1 * 3 + 2] = 0) then
          begin
            p1[x1 * 3] := Min(255, p1[x1 * 3] + p2[x1 * 3]);
            p1[x1 * 3 + 1] := Min(255, p1[x1 * 3 + 1] + p2[x1 * 3 + 1]);
            p1[x1 * 3 + 2] := Min(255, p1[x1 * 3 + 2] + p2[x1 * 3 + 2]);        //50%
            p1[x1 * 3] := Min(255, (p1[x1 * 3] div 2) + (p2[x1 * 3] div 2));
            p1[x1 * 3 + 1] := Min(255, (p1[x1 * 3 + 1] div 2) + (p2[x1 * 3 + 1] div
              2));
            p1[x1 * 3 + 2] := Min(255, (p1[x1 * 3 + 2] div 2) + (p2[x1 * 3 + 2] div
              2));
          end;    end;
      end;
    end;end.
    采用混合算法后你不用担心黑边问题了。
      

  5.   

    哦,错了句代码;公司显示器太差,眼都花了      //不是黑色则进行处理,因为黑色要作为透明色
          if (p2[x1 * 3] <> 0) or (p2[x1 * 3 + 1] = 0) or (p2[x1 * 3 + 2] = 0) then
    这句是错的,修改为下面这样
          //不是黑色则进行处理,因为黑色要作为透明色
          if (p2[x1 * 3] <> 0) or (p2[x1 * 3 + 1] <> 0) or (p2[x1 * 3 + 2] <> 0) then每个里面都有这句要改
      

  6.   

    你的思路就错了,本来根本就不存在这个所谓的问题。你这其实是两次Alpha混合,"所以先在一个画板上画出来了这个文字",这一步相对于就把32位图的Alpha通道丢失了,后面根本就无法还原。就算要分成两步来做,第一步输出的文字图层也应该是32位色的位图。文字区域只有一种颜色,包括边缘。不同的只是Alpha通道的值。
      

  7.   

    ehom(?!) :那这个正确的思路应该是什么样子的呢?