C#给图片加水印,可设置透明度,设置水印的位置可以看一下上一篇

/// <summary>
/// Creating a Watermarked Photograph with GDI+ for .NET
/// </summary>
/// <param name="rSrcImgPath">原始图片的物理路径</param>
/// <param name="rMarkImgPath">水印图片的物理路径</param>
/// <param name="rMarkText">水印文字(不显示水印文字设为空串)</param>
/// <param name="rDstImgPath">输出合成后的图片的物理路径</param>
public void BuildWatermark(string rSrcImgPath, string rMarkImgPath, string rMarkText, string rDstImgPath)
{
//以下(代码)从一个指定文件创建了一个Image 对象,然后为它的 Width 和 Height定义变量。
//这些长度待会被用来建立一个以24 bits 每像素的格式作为颜色数据的Bitmap对象。
Image imgPhoto = Image.FromFile(rSrcImgPath);
int phWidth = imgPhoto.Width;
int phHeight = imgPhoto.Height;
Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(, );
Graphics grPhoto = Graphics.FromImage(bmPhoto);
//这个代码载入水印图片,水印图片已经被保存为一个BMP文件,以绿色(A=0,R=0,G=255,B=0)作为背景颜色。
//再一次,会为它的Width 和Height定义一个变量。
Image imgWatermark = new Bitmap(rMarkImgPath);
int wmWidth = imgWatermark.Width;
int wmHeight = imgWatermark.Height;
//这个代码以100%它的原始大小绘制imgPhoto 到Graphics 对象的(x=0,y=0)位置。
//以后所有的绘图都将发生在原来照片的顶部。
grPhoto.SmoothingMode = SmoothingMode.AntiAlias;
grPhoto.DrawImage(
imgPhoto,
new Rectangle(, , phWidth, phHeight),
,
,
phWidth,
phHeight,
GraphicsUnit.Pixel);
//为了最大化版权信息的大小,我们将测试7种不同的字体大小来决定我们能为我们的照片宽度使用的可能的最大大小。
//为了有效地完成这个,我们将定义一个整型数组,接着遍历这些整型值测量不同大小的版权字符串。
//一旦我们决定了可能的最大大小,我们就退出循环,绘制文本
int[] sizes = new int[] { , , , , , , };
Font crFont = null;
SizeF crSize = new SizeF();
for (int i = ;i < ;i++)
{
crFont = new Font("arial", sizes[i],
FontStyle.Bold);
crSize = grPhoto.MeasureString(rMarkText,
crFont);
if ((ushort)crSize.Width < (ushort)phWidth)
break;
}
//因为所有的照片都有各种各样的高度,所以就决定了从图象底部开始的5%的位置开始。
//使用rMarkText字符串的高度来决定绘制字符串合适的Y坐标轴。
//通过计算图像的中心来决定X轴,然后定义一个StringFormat 对象,设置StringAlignment 为Center。
int yPixlesFromBottom = (int)(phHeight * .);
float yPosFromBottom = ((phHeight -
yPixlesFromBottom) - (crSize.Height / ));
float xCenterOfImg = (phWidth / );
StringFormat StrFormat = new StringFormat();
StrFormat.Alignment = StringAlignment.Center;
//现在我们已经有了所有所需的位置坐标来使用60%黑色的一个Color(alpha值153)创建一个SolidBrush 。
//在偏离右边1像素,底部1像素的合适位置绘制版权字符串。
//这段偏离将用来创建阴影效果。使用Brush重复这样一个过程,在前一个绘制的文本顶部绘制同样的文本。
SolidBrush semiTransBrush2 =
new SolidBrush(Color.FromArgb(, , , ));
grPhoto.DrawString(rMarkText,
crFont,
semiTransBrush2,
new PointF(xCenterOfImg + , yPosFromBottom + ),
StrFormat);
SolidBrush semiTransBrush = new SolidBrush(
Color.FromArgb(, , , ));
grPhoto.DrawString(rMarkText,
crFont,
semiTransBrush,
new PointF(xCenterOfImg, yPosFromBottom),
StrFormat);
//根据前面修改后的照片创建一个Bitmap。把这个Bitmap载入到一个新的Graphic对象。
Bitmap bmWatermark = new Bitmap(bmPhoto);
bmWatermark.SetResolution(
imgPhoto.HorizontalResolution,
imgPhoto.VerticalResolution);
Graphics grWatermark =
Graphics.FromImage(bmWatermark);
//通过定义一个ImageAttributes 对象并设置它的两个属性,我们就是实现了两个颜色的处理,以达到半透明的水印效果。
//处理水印图象的第一步是把背景图案变为透明的(Alpha=0, R=0, G=0, B=0)。我们使用一个Colormap 和定义一个RemapTable来做这个。
//就像前面展示的,我的水印被定义为100%绿色背景,我们将搜到这个颜色,然后取代为透明。
ImageAttributes imageAttributes =
new ImageAttributes();
ColorMap colorMap = new ColorMap();
colorMap.OldColor = Color.FromArgb(, , , );
colorMap.NewColor = Color.FromArgb(, , , );
ColorMap[] remapTable = { colorMap };
//第二个颜色处理用来改变水印的不透明性。
//通过应用包含提供了坐标的RGBA空间的5x5矩阵来做这个。
//通过设定第三行、第三列为0.3f我们就达到了一个不透明的水平。结果是水印会轻微地显示在图象底下一些。
imageAttributes.SetRemapTable(remapTable,
ColorAdjustType.Bitmap);
float[][] colorMatrixElements = {
new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
};
ColorMatrix wmColorMatrix = new
ColorMatrix(colorMatrixElements);
imageAttributes.SetColorMatrix(wmColorMatrix,
ColorMatrixFlag.Default,
ColorAdjustType.Bitmap);
//随着两个颜色处理加入到imageAttributes 对象,我们现在就能在照片右手边上绘制水印了。
//我们会偏离10像素到底部,10像素到左边。
int markWidth;
int markHeight;
//mark比原来的图宽
if (phWidth <= wmWidth)
{
markWidth = phWidth - ;
markHeight = (markWidth * wmHeight) / wmWidth;
}
else if (phHeight <= wmHeight)
{
markHeight = phHeight - ;
markWidth = (markHeight * wmWidth) / wmHeight;
}
else
{
markWidth = wmWidth;
markHeight = wmHeight;
}
int xPosOfWm = ((phWidth - markWidth) - );
int yPosOfWm = ;
grWatermark.DrawImage(imgWatermark,
new Rectangle(xPosOfWm, yPosOfWm, markWidth,
markHeight),
,
,
wmWidth,
wmHeight,
GraphicsUnit.Pixel,
imageAttributes);
//最后的步骤将是使用新的Bitmap取代原来的Image。 销毁两个Graphic对象,然后把Image 保存到文件系统。
imgPhoto = bmWatermark;
grPhoto.Dispose();
grWatermark.Dispose();
imgPhoto.Save(rDstImgPath, ImageFormat.Jpeg);
imgPhoto.Dispose();
imgWatermark.Dispose();
}

C#给图片加水印,可设置透明度的更多相关文章

  1. java 图片加水印,设置透明度。说明非常具体

    package com.yidao.common; import java.awt.AlphaComposite; import java.awt.Graphics2D; import java.aw ...

  2. Java图片处理(二)图片加水印

    图片加水印,是通过图片重叠绘制实现的.实现代码如下: public static void press(String pressImg, String pressText, String target ...

  3. c#封装DBHelper类 c# 图片加水印 (摘)C#生成随机数的三种方法 使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象 c# 制作正方形图片 JavaScript 事件循环及异步原理(完全指北)

    c#封装DBHelper类   public enum EffentNextType { /// <summary> /// 对其他语句无任何影响 /// </summary> ...

  4. 火车头dede采集接口,图片加水印,远程图片本地化,远程无后缀的无图片本地化

    <?php /* [LocoySpider] (C)2005-2010 Lewell Inc. 火车采集器 DedeCMS 5.7 UTF8 文章发布接口 Update content: 图片加 ...

  5. thinkphp 3.2.3整合ueditor 1.4,给上传的图片加水印

    今天分享一下thinkphp 3.2.3整合ueditor 1.4,给上传的图片加水印.博主是新手,在这里卡住了很久(>_<) thinkphp 3.2.3整合ueditor 1.4 下载 ...

  6. PHP给图片加水印

    <?php /** *图片加水印 *@param $srcImg 原图 *@param $waterImg 水印图片 *@param $savepath 保存路径 *@param $savena ...

  7. 如何用node.js批量给图片加水印

    上一篇我们讲了如何用node.js给图片加水印,但是只是给某一张图片加,并没有涉及到批量处理.这一篇,我们学习如果批量进行图片加水印处理. 一.准备工作: 首先,你要阅读完这篇文章:http://ww ...

  8. php对图片加水印--将文字作为水印加到图片

    方法代码: /**  * 图片加水印(适用于png/jpg/gif格式)  *  * @author flynetcn  *  * @param $srcImg  原图片  * @param $wat ...

  9. php对图片加水印--将一张图片作为水印加到另一张图片

    代码如下: /**  * 图片加水印(适用于png/jpg/gif格式)  *  * @param $srcImg  原图片  * @param $waterImg 水印图片  * @param $s ...

随机推荐

  1. windows下命令行切换目录

    1.切换目录 C:\Users\MACHENIKE> cd H:/www C:\Users\MACHENIKE>H: H:\www> 2.查看目录文件 H:\www>dir

  2. 【数论】P1029 最大公约数和最小公倍数问题

    题目链接 P1029 最大公约数和最小公倍数问题 思路 如果有两个数a和b,他们的gcd(a,b)和lcm(a,b)的乘积就等于ab. 也就是: ab=gcd(a,b)*lcm(a,b) 那么,接下来 ...

  3. The puzzle

    The puzzle: 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6489 找大佬讲了一下这道题,但还是不懂为什么要这样做,先记录一下以后再研究研究; ...

  4. Pytest权威教程21-API参考-04-钩子(Hooks)

    目录 钩子(Hooks) 引导时的Hook方法 初始化时的Hook方法 测试运行时的Hook方法 收集用例时的Hook方法 生成测试结果时的Hook方法 调试/交互Hook方法 返回: Pytest权 ...

  5. C# 百度API地址坐标互相转换

    通过C#代码将地址字符串转为经纬度坐标,或者将经纬度转为具体的地址字符串,在不通外网的项目中是有需求的. 具体步骤: 一.创建BaiduMapHelper,用于定义地址信息和请求. public st ...

  6. python3 枚举定义和使用

    定义 在某些情况下,一个类的对象是有限且固定的,比如季节类,它只有 4 个对象:再比如行星类,目前只有 8 个对象.这种实例有限且固定的类,在 Python 中被称为枚举类.程序有两种方式来定义枚举类 ...

  7. css,js 学习记录

    记录一些自己曾经阅读,值得收藏的网址 --(css3新特性) https://segmentfault.com/a/1190000010780991#articleHeader41 --CSS3 3D ...

  8. ubuntu之路——day3(本来打算做pytorch的练习 但是想到前段时间的数据预处理的可视化分析 就先总结一下)

    首先依托于一个场景来进行可视化分析 直接选了天池大数据竞赛的新人赛的一个活跃题目 用的方式也是最常用的数据预处理方式 [新人赛]快来一起挖掘幸福感!https://tianchi.aliyun.com ...

  9. java中nextLine()与next()的区别

    java中的next()和nextLine()还是有很大区别的. next()一定要读取到有效字符后才可以结束输入,对输入有效字符之前遇到的空格键.Tab键或Enter键等结束符,next()方法会自 ...

  10. 开启和关闭oracle数据库中的审计功能

    第1步:查看审计功能是否开启?SQL> show parameter audit;NAME                                 TYPE        VALUE-- ...