/// <summary> /// 为图片添加图片水印 /// </summary> /// <param name="parameters">添加图片水印相关参数体</param> /// <param name="errorMsg">错误信息</param> /// <returns>已加水印的图片数据流</returns> public static MemoryStream DrawImage(ImageWatermarkParameters parameters, out string errorMsg) { errorMsg = string.Empty; try { // 参数检查 if (!parameters.CheckAndSetDefault(out errorMsg)) throw new InvalidDataException(errorMsg); // 为源图片添加图片水印 Bitmap finalImage = AddWatermarkImageForSourceImage(parameters, out errorMsg); if (finalImage == null && !string.IsNullOrEmpty(errorMsg)) throw new InvalidDataException("生成水印图片失败:" + errorMsg); // 获取Bitmap的MemoryStream return GetMemoryStreamFromBitmap(finalImage, parameters.SourceImageFileExtensionName); } catch (Exception ex) { errorMsg = ex.Message.ToString(); return null; } }
/// <summary> /// 获取源图片和水印图片的数据流 /// </summary> /// <param name="parameters">参数实例</param> /// <param name="sourceImageStream">源图片数据流</param> /// <param name="waterImageStream">水印图片数据流</param> /// <param name="errorMsg">错误信息</param> /// <returns>是否获取成功</returns> private static bool GetSourceAndWatermarkImageStream(ImageWatermarkParameters parameters, out MemoryStream sourceImageStream, out MemoryStream waterImageStream, out string errorMsg) { errorMsg = string.Empty; // 根据是否设置图片路径来判断如何获取图片数据流,分别获取源图片和水印图片的数据流。 string scErrMsg = string.Empty, wmErrMsg = string.Empty; sourceImageStream = parameters.SourceImageStream == null ? GetImageMemoryStream(parameters.SourceImagePath, out scErrMsg) : parameters.SourceImageStream; waterImageStream = parameters.WatermarkImageStream == null ? GetImageMemoryStream(parameters.WatermarkImagePath, out wmErrMsg) : parameters.WatermarkImageStream; if (!string.IsNullOrEmpty(scErrMsg) || !string.IsNullOrEmpty(wmErrMsg)) { errorMsg = "通过图片路径获取数据流失败:" + scErrMsg + ";" + wmErrMsg; return false; } return true; }
/// <summary> /// 为源图片添加图片水印 /// </summary> /// <param name="parameters">参数集合</param> /// <param name="errMsg">错误消息</param> /// <returns>添加完水印的位图对象</returns> private static Bitmap AddWatermarkImageForSourceImage(ImageWatermarkParameters parameters, out string errMsg) { Image sourceImage = null; Bitmap sourceBitmap = null; Graphics sourceGraphics = null; Image watermarkImage = null; Graphics watermarkGraphics = null; errMsg = string.Empty; try { // 获取源图片和水印图片的数据流 MemoryStream sourceImageStream, waterImageStream = null; if (GetSourceAndWatermarkImageStream(parameters, out sourceImageStream, out waterImageStream, out errMsg) == false) throw new InvalidDataException(errMsg); sourceImage = Image.FromStream(sourceImageStream as Stream); // 实例化一个与源图大小一样、分辨率一致的位图对象,并将其载入Graphics对象中,以便后续编辑; // 需要根据图像的像素格式来判断是否需要重新绘制该图像 sourceBitmap = (IsPixelFormatIndexed(sourceImage.PixelFormat)) ? RedrawBitmapByImage(sourceImage) : new Bitmap(sourceImage.Width, sourceImage.Height, sourceImage.PixelFormat); sourceBitmap.SetResolution(sourceImage.HorizontalResolution, sourceImage.VerticalResolution); sourceGraphics = Graphics.FromImage(sourceBitmap); // SmoothingMode:指定是否将平滑处理(消除锯齿)应用于直线、曲线和已填充区域的边缘。 // 成员名称 说明 // AntiAlias 指定消除锯齿的呈现。 // Default 指定不消除锯齿。 // HighQuality 指定高质量、低速度呈现。 // HighSpeed 指定高速度、低质量呈现。 // Invalid 指定一个无效模式。 // None 指定不消除锯齿。 sourceGraphics.SmoothingMode = SmoothingMode.AntiAlias; // 将源图像Image对象添加到绘图板中 sourceGraphics.DrawImage(sourceImage, new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), 0, 0, sourceImage.Width, sourceImage.Height, GraphicsUnit.Pixel); // // 按照源图片的操作方式,需要创建水印图片的Image对象、位图对象, // 只是需要根据输入参数来调整水印图片在源图片中的位置、显示效果等。 watermarkImage = new Bitmap(waterImageStream); // 这里尤其注意,生成新位图的时候,载入的是已经添加了源图片作为背景的位图哦! // 并将设定好分辨率的位图载入到新的Graphics实例中,以进一步绘制水印。 Bitmap watermarkBitmap = new Bitmap(sourceBitmap); watermarkBitmap.SetResolution(sourceImage.HorizontalResolution, sourceImage.VerticalResolution); watermarkGraphics = Graphics.FromImage(watermarkBitmap); // 通过imageAttributes实例来设定水印图片的绘制效果,包括位置和现实效果等 ImageAttributes imageAttributes = GetImageAttributesInstance(parameters.Alpha); // 获取水印图片的起始位置 int xPosOfWm, yPosOfWm = 0; GetWatermarkImagePosition(parameters.WmPosition, sourceImage.Width, sourceImage.Height, watermarkImage.Width, watermarkImage.Height, out xPosOfWm, out yPosOfWm); // 绘制水印图片 watermarkGraphics.DrawImage(watermarkImage, new Rectangle(xPosOfWm, yPosOfWm, watermarkImage.Width, watermarkImage.Height), 0, 0, watermarkImage.Width, watermarkImage.Height, GraphicsUnit.Pixel, imageAttributes); return watermarkBitmap; } catch (Exception e) { errMsg = e.Message.ToString(); return null; } finally { // 释放 if (sourceImage != null) sourceImage.Dispose(); if (sourceBitmap != null) sourceBitmap.Dispose(); if (sourceGraphics != null) sourceGraphics.Dispose(); if (watermarkImage != null) watermarkImage.Dispose(); if (watermarkGraphics != null) watermarkGraphics.Dispose(); } }