.NET给图片加背景地图和水印_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > .NET给图片加背景地图和水印

.NET给图片加背景地图和水印

 2013/7/17 16:14:04  lvrocky  博客园  我要评论(0)
  • 摘要:usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Drawing;usingSystem.Drawing.Imaging;usingSystem.Drawing.Drawing2D;namespaceUtility{publicclassImageHelp{///<summary>
  • 标签:.net 图片 net
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace Utility
{
    public class ImageHelp
    {
        /// <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 static void BuildWatermark(int width, int height, string rSrcImgPath, string rMarkImgPath, string rMarkText, string rDstImgPath)
        {

            Image imgPhoto = Image.FromFile(rSrcImgPath);
            int phWidth = width;
            int phHeight = height;
            Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);
            bmPhoto.SetResolution(72, 72);

            //根据前面修改后的照片创建一个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(255, 0, 255, 0);
            colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
            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);

            Graphics grPhoto = Graphics.FromImage(bmWatermark);
            //这个代码载入水印图片,水印图片已经被保存为一个BMP文件,以绿色(A=0,R=0,G=255,B=0)作为背景颜色。
            //再一次,会为它的Width 和Height定义一个变量。
            Image imgWatermark = new Bitmap(rMarkImgPath);
            int wmWidth = width;
            int wmHeight = height;
            //这个代码以100%它的原始大小绘制imgPhoto 到Graphics 对象的(x=0,y=0)位置。
            //以后所有的绘图都将发生在原来照片的顶部。
            grPhoto.SmoothingMode = SmoothingMode.Default;
            grPhoto.FillRectangle(new SolidBrush(Color.White), 0, 0, width, height);
            Rectangle rect = new Rectangle(0, 0, phHeight, phHeight);
            if (imgPhoto.Width < width && imgPhoto.Height < height)
            {
                rect = new Rectangle((phWidth - imgPhoto.Width) / 2, (phHeight - imgPhoto.Height) / 2, imgPhoto.Width, imgPhoto.Height);

            }
            else
            {
                rect = new Rectangle(0, 0, phWidth, phHeight);
            }

     
            int markWidth;
            int markHeight;
            //mark比原来的图宽
            if (phWidth <= wmWidth)
            {
                markWidth = phWidth - 10;
                markHeight = (markWidth * wmHeight) / wmWidth;
            }
            else if (phHeight <= wmHeight)
            {
                markHeight = phHeight - 10;
                markWidth = (markHeight * wmWidth) / wmHeight;
            }
            else
            {
                markWidth = wmWidth;
                markHeight = wmHeight;
            }
            int xPosOfWm = ((phWidth - markWidth) - 10);
            int yPosOfWm = 10;
            grWatermark.DrawImage(imgWatermark,
                 new Rectangle(xPosOfWm, yPosOfWm, markWidth,
                 markHeight),
                 0,
                 0,
                 wmWidth,
                 wmHeight,
                 GraphicsUnit.Pixel,
                 imageAttributes);//先绘制水印
            grWatermark.DrawImage(
              imgPhoto,
              rect,
              0,
              0,
              imgPhoto.Width,
              imgPhoto.Height,
              GraphicsUnit.Pixel);//再绘制图片

            #region 水印文字调整

            //自动调整水印文字大小
            int[] sizes = new int[] { 16, 14, 12, 10, 8, 6, 4 };
            Font crFont = null;
            SizeF crSize = new SizeF();
            for (int i = 0; i < 7; 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 * .05);
            //float yPosFromBottom = ((phHeight -
            //     yPixlesFromBottom) - (crSize.Height / 2));
            //float xCenterOfImg = (phWidth / 2);//位置在正中
            int yPosFromBottom = (new Random().Next(10, height));
            int xCenterOfImg = (new Random().Next(10, width));
            StringFormat StrFormat = new StringFormat();
            StrFormat.Alignment = StringAlignment.Center;
            //现在我们已经有了所有所需的位置坐标来使用60%黑色的一个Color(alpha值153)创建一个SolidBrush 。
            //在偏离右边1像素,底部1像素的合适位置绘制版权字符串。
            //这段偏离将用来创建阴影效果。使用Brush重复这样一个过程,在前一个绘制的文本顶部绘制同样的文本。
            SolidBrush semiTransBrush2 =
                 new SolidBrush(Color.FromArgb(153, 222, 0, 0));//调整水印文字的颜色
            grWatermark.DrawString(rMarkText,
                 crFont,
                 semiTransBrush2,
                 new PointF(xCenterOfImg + 1, yPosFromBottom + 1),
                 StrFormat);
            SolidBrush semiTransBrush = new SolidBrush(
                 Color.FromArgb(153, 255, 255, 255));
            grWatermark.DrawString(rMarkText,
                 crFont,
                 semiTransBrush,
                 new PointF(xCenterOfImg, yPosFromBottom),
                 StrFormat);
            //随着两个颜色处理加入到imageAttributes 对象,我们现在就能在照片右手边上绘制水印了。
            //我们会偏离10像素到底部,10像素到左边。
            #endregion
            //最后的步骤将是使用新的Bitmap取代原来的Image。 销毁两个Graphic对象,然后把Image 保存到文件系统。
            imgPhoto = bmWatermark;
            grPhoto.Dispose();
            grWatermark.Dispose();
            imgPhoto.Save(rDstImgPath, ImageFormat.Jpeg);
            imgPhoto.Dispose();
            imgWatermark.Dispose();
        }

    }
}

 

发表评论
用户名: 匿名