zoukankan      html  css  js  c++  java
  • .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();
            }
    
        }
    }
  • 相关阅读:
    [Swift]LeetCode380. 常数时间插入、删除和获取随机元素 | Insert Delete GetRandom O(1)
    [Swift]LeetCode378. 有序矩阵中第K小的元素 | Kth Smallest Element in a Sorted Matrix
    说说心声------ 一些经历
    安装eclipse maven插件m2eclipse No repository found containing
    苹果浏览器实战(三)
    CSDN挑战编程——《绝对值最小》
    高可用技术工具包 High Availability Toolkit
    jstl 标签 循环 序号
    坚向的ViewPager,上下滑动的组件,android上下滑动 VerticalPager
    Php socket数据编码
  • 原文地址:https://www.cnblogs.com/lvrocky/p/3195927.html
Copyright © 2011-2022 走看看