C#图片处理之:给你的图片打上LOGO

来源:网络整理 责任编辑:栏目编辑 发表时间:2013-07-01 14:07 点击:

做图片处理软件,肯定会遇到这样的需求:如何把一张图片放在另一张图片上,比如在大图片中打上公司或个人的Logo等等。

其实原理很简单。假设我们有一张 800 * 600 的大图片(Bitmap b0),想在(10,10)的位置上打上Logo(Bitmap b1),Logo图片大小是 150 * 30。很简单,我们以大图片的(10,10)位置作为起始位置,做一个150 * 30 的矩形,把Logo图片整个替换这个矩形。

老规矩,还是用BitmapData来帮助我们实现这个功能。

// 取以大图(X,Y)为起点,w * h 的矩形区域
BitmapData srcData = b0.LockBits(new Rectangle(X,Y,w,h),ImageLockMode.WriteOnly,PixelFormat.Format24bppRgb);

// 取整个Logo
BitmapData dstData = b1.LockBits(new Rectangle(0,0,w,h),ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

unsafe
{
    byte* pIn = (byte*)srcData.Scan0.ToPointer();  
    byte* pLogo = (byte*)dstData.Scan0.ToPointer();

    for (int y = 0; y < h; y++)
    {
        for (int x = 0; x < w; x++)
        {

  // 复制Logo图的像素   
  pIn[0] = (byte)pLogo[0];
  pIn[1] = (byte)pLogo[1];
  pIn[2] = (byte)pLogo[2];

  pIn += 3;
  pLogo += 3;
        }

        pIn += srcData.Stride - w * 3;
        pLogo += dstData.Stride - w * 3;
    }

    b0.UnlockBits(srcData);
    b1.UnlockBits(dstData);
}

这样,为图片打Logo的功能就实现了。当然,还可以有别的方法,比如用BitBlt这个API函数,或者使用GDI+的DrawImage函数。

但这样有个小问题,Logo区域永远是个矩形。假如我的Logo是个圆形,只希望在大图上出现圆形的Logo而不是整块矩形,那又该如何实现呢?

这个问题其实可以这样理解:我们让Logo的背景变透明。而所谓透明,就是两张图片叠加时,上层图片“透明”区域中的像素,仍然使用下层图的相应像素来代替。但在RGB模式下,并没有“透明”这个概念(我们的讨论都在用PixelFormat.Format24bppRgb,PixelFormat.Format32bppArgb中的Alpha分量支持“透明度”),因此我们需要自己规定一种颜色,凡是这个颜色的,都作为“透明”处理。

比如,我们的Logo是黑底的,那么就指定黑色作为透明色。

修改算法也很简单,凡是遇到Logo图中像素颜色是黑色(当然这是个参数,可以自己改)的,就用大图相应位置的颜色来代替,否则还是使用Logo的像素色。下面是算法:

// 因为有可能要回写,所以原图的 ImageLockMode 这次是 ReadWrite
BitmapData srcData = b0.LockBits(new Rectangle(X, Y, w, h), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

BitmapData dstData = b1.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

unsafe
{
    byte* pIn = (byte*)srcData.Scan0.ToPointer();
    byte* pLogo = (byte*)dstData.Scan0.ToPointer();

    for (int y = 0; y < h; y++)
    {
        for (int x = 0; x < w; x++)
        {

  // 判断当前点是否透明色
  // 取得当前色
  Color c = Color.FromArgb(pLogo[2], pLogo[1], pLogo[0]);
  if (!ColorIsSimilar(c, TransColor, delta))
  {
   // 不是透明色,b0当前位置的颜色用b1对应位置的来代替
   pIn[0] = (byte)pLogo[0];
   pIn[1] = (byte)pLogo[1];
   pIn[2] = (byte)pLogo[2];
  }

  pIn += 3;
  pLogo += 3;
        }

        pIn += srcData.Stride - w * 3;
        pLogo += dstData.Stride - w * 3;
    }

    b0.UnlockBits(srcData);
    b1.UnlockBits(dstData);
}

我们在上面的算法中出现了另一个小算法,判断颜色C0,C1是否相等。当然如果两个颜色的RGB分量都相等那

    发表评论
    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
    用户名: 验证码:点击我更换图片
    最新评论 更多>>

    推荐热点

    • 用C#制作屏幕捕获程序
    • .NET程序员项目开发必知必会—Dev环境中的集成测试用例执行时上
    • 遍历ArrayList易犯错误
    • C#对XML操作:一个处理XML文件的类(1)
    • .NET简谈反射(动态调用)
    • 使用C#编写LED样式时钟控件
    • DataList嵌套问题 如何删除内层子DataList的记录
    • 怎样用C#实现完整文档打印功能
    • .NET简谈自定义事务资源管理器
    网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
    Copyright © 2008-2015 计算机技术学习交流网. 版权所有

    豫ICP备11007008号-1