透明版权 透明LOGO - 亲,注意身体

konooo 2021-08-14 原文


透明版权 透明LOGO


  刚才在提问区解答了一个问题,即如何给图片加半透明度水印,实际上由于透明度算法是最早被发现也是最简单和基本的算法之一,因此这个方法实际上很直
观。这里单独发帖再来解释下这个问题。首先我们强调一下opacity的概念,是“不透明度”,它表示的是两个图层之间的关系,即该属性隶属于本图层,它
表示与本图层下面图层之间的像素合成关系,当opacity=100%时,表示本图层完全不透明,因此下面的像素完全被遮挡。当opacity=0时,表
示本图层完全透明,即能看到下面的图层。这是photoshop中最基本的一个算法,表达如下:
        像素结果=底部图层*(1-opacity)+本图层*opacity;
        当有多个图层x0,x1,x2混合时,表达如下:(最底层的不透明度为1)
        x=((1-k1)x0+k1*x1)(1-k2)+k2*x2= (1-k1)(1-k2)x0 + k1(1-k2)x1 + k2*x2;

        那么绘制透明度水印的方法也就非常直观了,因为类库中的ImageAttributes属性里面并没有提供像素合成的绘制选项,因此我们
自己实现上面的算法。方法是:首先准备一个小的水印图片,我们先把原图在水印下面的部分绘制上去,然后在吧水印的文本或图片绘制上去,然后把原图和水印图
片的内存数据锁定(防止操作系统移动内存),然后直接用上面的算法改写原图的位图数据,解锁内存即得到最终加了水印的图片。

      
代码如下:下面是绘制文本类型的水印,只需提供水印文本内容,绘制起始坐标即可。注意,为了简单直观起见,代码中都没有做参数验证,例如水印是否超出原图
范围,如果超出范围将引发对超过内存边界的访问限制(引发异常)。下面使用了unsafe代码,因此项目属性->Build中,应勾选允许不安全代
码,否则无法编译。 在下面代码中的定位方式是非常熟悉的。再次强调的是以下的概念:
       scan0:指针,内存数据的起始地址。(换句话说,就是指向第一个扫描行第一个像素的Blue)。
       bpp:bit per pixel。
       stride:扫描行宽度,=width*bpp/8 并在结尾补0~3个字节的0,以凑齐到4字节整数倍。
       之所以横坐标乘以3是因为我们锁定的方式是24bppRgb(最后一个参数指定了数据的bpp),这意味这每个像素占据了3个字节,因此i要乘以3来跳跃到下一个像素。如果用32bppRGB锁定,则每个像素在内存占据4字节,相应的i应该乘以4。

Code-文本水印
/// <summary>
/// 给一个位图绘制水印文字(没有验证水印是否超出图片边界!)
/// </summary>
/// <param name=”text”>水印文本</param>
/// <param name=”x”>起始点</param>
/// <param name=”y”>起始点</param>
/// <param name=”opacity”>不透明度,0~1</param>
private Bitmap DrawWatermark(Image image,string text, Font font,Brush brush,int x,int y,double opacity)
{
    Bitmap bm1 
= new Bitmap(image);
    Graphics g1
=Graphics.FromImage(bm1);
    
//测量水印文字的大小,然后申请一个新的位图
    SizeF sizef=g1.MeasureString(text,font);
    Bitmap bm2
=new Bitmap((int)sizef.Width,(int)sizef.Height);
    Graphics g2
=Graphics.FromImage(bm2);
    g2.DrawImage(bm1, 
0,0,new Rectangle(x, y, bm2.Width, bm2.Height),GraphicsUnit.Pixel);
    g2.DrawString(text,font,brush,
0,0);
    BitmapData data1
=bm1.LockBits(new Rectangle(0,0,bm1.Width,bm1.Height),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
    BitmapData data2
=bm2.LockBits(new Rectangle(0,0,bm2.Width,bm2.Height),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
    
unsafe
    {
        
byte* p1=(byte*)(void*)data1.Scan0;
        
byte* p2=(byte*)(void*)data2.Scan0;
        
for(int j=0;j<bm2.Height;j++)
        {
            
for(int i=0;i<bm2.Width*3;i++)
            {
                p1[(y
+j)*data1.Stride+i]=(byte)(p1[(y+j)*data1.Stride+i]*(1opacity)+opacity*p2[j*data2.Stride+i]);
            }
        }
        bm1.UnlockBits(data1);
        bm2.UnlockBits(data2);
    }
    
return bm1; 
}

还有一种情况是,我们事先做作好水印,它是一个图片,更多的人在photoshop中使用一个自己设计好的logo,保存为一个“画笔形状”,制作时只要
选中此画笔一盖就好了。实际上这种类型的水印是一个图片,为了加这种类型的水印,引入下面的overload方法:指定水印图片和透明色。

Code-图片水印
/// <param name=”image”>原图</param>
/// <param name=”wmImg”>水印图片</param>
/// <param name=”key”>透明色</param>
/// <param name=”x”>起始点</param>
/// <param name=”y”></param>
/// <param name=”opacity”>不透明度</param>
/// <returns></returns>
private Bitmap DrawWatermark(Image image, Bitmap wmImg, Color key,int x, int y, double opacity)
{
    Bitmap bm1 
= new Bitmap(image);     //克隆原图,它也是我们的返回值
    Bitmap bm2 
= new Bitmap(wmImg.Width, wmImg.Height);     //准备的水印图片
    Graphics g2 
= Graphics.FromImage(bm2);
    ImageAttributes att 
= new ImageAttributes();
    att.SetColorKey(key, key, ColorAdjustType.Bitmap);     //设定透明色
    g2.DrawImage(bm1, 
00new Rectangle(x, y, bm2.Width, bm2.Height), GraphicsUnit.Pixel);
    g2.DrawImage(wmImg, 
new Rectangle(0,0,bm2.Width,bm2.Height),00,bm2.Width,bm2.Height,GraphicsUnit.Pixel,att);
    g2.Dispose();
    。。。。这里的代码和上面的方法代码相同,因此省略
    
return bm1;
}

以上两种效果的截图:
(1)    (2)
          
       

posted on
2008-03-21 17:14 
亲,注意身体 
阅读(882
评论(0
编辑 
收藏 
举报

 

版权声明:本文为konooo原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/konooo/articles/1116774.html

透明版权 透明LOGO - 亲,注意身体的更多相关文章

  1. 如何配置阿里公共DNS——上网加速、无广告、无劫持、访问网站响应快 – it小白

    如何配置阿里公共DNS——上网加速、无广告、无劫持、访问网站响应快         我们都知道,我们要能上网, […]...

  2. Ubuntu下哪个PDF阅读器更好使??? – PhoenixMY

    Ubuntu下哪个PDF阅读器更好使??? 根据windows系统上的经验,果断选择了foxit reader […]...

  3. 【书单】图解数学学习法 让抽象的数学直观起来 – sirglory

    【书单】图解数学学习法 让抽象的数学直观起来 2017.4.9-4.10 图解数学学习法 让抽象的数学直观起来 […]...

  4. Integer 类型初始化 && java 形参

    参考:http://blog.sina.com.cn/s/blog_6b8b431d0100y8s0.html […]...

  5. Spring Boot 2.0深度实践之系列总览 – bijian1013

    Spring Boot 2.0深度实践之系列总览 一.Spring Boot2.0易学难精 1.Spring  […]...

  6. ListBox控件使用 (转载) – 滴墨成伤

    ListBox控件使用 (转载) ListBox控件属性介绍: SelectIndex:当前选中的列表项的序号 […]...

  7. 触摸屏技术原理介绍 – resound

    触摸屏技术原理介绍 随着使用电脑作为信息来源的与日俱增,触摸屏以其易于使用、坚固耐用、反应速度快、 节省空间等 […]...

  8. Firefox — 火狐浏览器下载

    http://www.firefox.com.cn/download/    ...

随机推荐

  1. Github 访问加速

    起因 在中国,因为网络条件的一些问题,同时因为Github没有在中国的CDN服务器,所以访问Github的速度 […]...

  2. 一个提升英文单词拼写检测性能 1000 倍的算法?

    序言 小明同学上一次在产品经理的忽悠下,写好了一个中英文拼写纠正工具:https://github.com/h […]...

  3. 关于 JOIN 耐心总结,学不会你打我系列

    现在随着各种数据库框架的盛行,在提高效率的同时也让我们忽略了很多底层的连接过程,这篇文章是对 SQL 连接过程 […]...

  4. Oracle数据库安装和破解

    Oracle数据库安装教程 作者:黑小子–余 Qq:2931445528 微信:Y29314455 […]...

  5. optimizing Wi-Fi solution for International School

    optimizing Wi-Fi solution for International School Cisc […]...

  6. 【WPF】学习笔记(一)——做一个简单的电子签名板

    参加实习(WPF)已经有两个多周的时间了,踩了一些坑,也算积累了一些小东西,准备慢慢拿出来分享一下。(●\&# […]...

  7. 为企业服务器配置RAID0、raid1、 raid10、raid5、raid6、等常见RAID

    RAID卡操作手册先从开机启动时如何进入管理界面开始介绍: 1)当机器开启后,显示器出现阵列卡检测信息时,会提 […]...

  8. 8个Docker的真实应用场景(转)

    原文地址:http://dockone.io/article/126 下面是我总结的一些Docker的使用场景 […]...

展开目录

目录导航