给图片加水印
public void DoAddMark(object ParameterInfo) { #region 拆分参数 List<object> listParameter = (List<object>)ParameterInfo; ConnParameter connpar = (ConnParameter)listParameter[0]; //连接数据库参数 string[] strImgPath = (string[])listParameter[1]; //图片源路径 string[] strTargeFilePath = (string[])listParameter[2]; //目标路径 #endregion //通知主界面,我已经开始了,strImgPath.Length表示进度条最大值 // threadStartEvent.Invoke(strImgPath.Length, new EventArgs()); //遍历strImgPath string strThreadName = Thread.CurrentThread.Name.ToString(); DateTime dateTimeStart = DateTime.Now; List<object> ListStart = new List<object>(); List<object> ListNow = new List<object>(); List<object> ListEnd = new List<object>(); ListStart.Add(strThreadName); ListStart.Add(strImgPath.Length); threadStartEvent.Invoke((object)ListStart, new EventArgs()); Log.LogInfo(Thread.CurrentThread.Name.ToString(), DateTime.Now + " ======= " + Thread.CurrentThread.Name.ToString() + " ======= " + strImgPath.Length + " 张图片========================================"); try { for (int num = 1; num <= strImgPath.Length; num++) { ListNow.Clear(); string strSourseImgPath = strImgPath[num - 1].ToString(); //源文件夹目标 string[] strSourseImgPathSplit = strSourseImgPath.Split('\\'); string strSourseImgIdAndType=strSourseImgPathSplit[strSourseImgPathSplit.Length - 1].ToString (); string[] strImgIdSplit = strSourseImgIdAndType.Split('.'); string strImgId = strSourseImgIdAndType.Substring(0, strSourseImgIdAndType.Length - strImgIdSplit[strImgIdSplit.Length-1].Length-1); //图片Id if (Directory.Exists(strTargeFilePath[num - 1]) == false) { Directory.CreateDirectory(strTargeFilePath[num - 1]); } string strTargetImaPath = strTargeFilePath[num - 1] + @"\" + strImgId + ".jpg"; //目标路径 //加水印 PictureAddMark(connpar, num, strImgId, strSourseImgPath, strTargetImaPath); //通知主界面,我正在执行,num表示进度条当前进度 ListNow.Add(strThreadName); ListNow.Add(num); nowValue.Invoke((object)ListNow, new EventArgs()); } DateTime dateTimeEnd = DateTime.Now; string strTimeDiff = string.Empty; strTimeDiff = DateDiff(dateTimeStart, dateTimeEnd); ListEnd.Add(strThreadName); ListEnd.Add(strTimeDiff); threadEndEvent.Invoke((object)ListEnd, new EventArgs()); Log.LogInfo(Thread.CurrentThread.Name.ToString(), "=========================================================================================================="); } catch (Exception ex) { throw new Exception(ex.Message.ToString()); } } /// <summary> /// 获取线程的执行时间 /// </summary> /// <param name="TimeStart">此线程的开始时间</param> /// <param name="TimeEnd">此线程执行任务结束后的时间</param> /// <returns>差值</returns> private string DateDiff(DateTime TimeStart, DateTime TimeEnd) { string dateDiff = string.Empty; TimeSpan ts = TimeStart.Subtract(TimeEnd).Duration(); dateDiff = ts.Hours.ToString() + "h" + ts.Minutes.ToString() + "m" + ts.Seconds.ToString() + "s"; return dateDiff; } /// <summary> /// 加水印操作 /// </summary> /// <param name="ImgId">图片Id</param> /// <param name="SoursePath">源图片路径</param> /// <param name="TargePath">目标路径,即加水印之后的保存路径。</param> public static void PictureAddMark(ConnParameter cp, int ImgNum, string ImgId, string SoursePath, string TargePath) { #region 方法声明 AddWatermark awd = new AddWatermark(); //加水印 AddThreePoints atp = new AddThreePoints(); //取三点 #endregion try { //取三点 ShoesSign ss = atp.GetShoesSign(SoursePath); using (Bitmap imgPhoto = new Bitmap(Image.FromFile(SoursePath))) { //加水印处理 using (Bitmap ImageMark = awd.GetPictureWithWatermark(imgPhoto)) { //设置加水印之后图片的大小,bitmap,存储目录,图片质,如果bitmap不空并且图片大小转换成功则写日志 if (ImageMark != null&&KiSaveAsJPEG(ImageMark, TargePath, 60)==true) { //写日志 string strCurrentThreadName = Thread.CurrentThread.Name.ToString(); switch (strCurrentThreadName.Trim()) { case "thread1": Log.LogInfo(strCurrentThreadName, DateTime.Now + " " + strCurrentThreadName + " " + SoursePath + " 第" + ImgNum + "张加水印成功"); break; case "thread2": Log.LogInfo(strCurrentThreadName, DateTime.Now + " " + strCurrentThreadName + " " + SoursePath + " 第" + ImgNum + "张加水印成功"); break; case "thread3": Log.LogInfo(strCurrentThreadName, DateTime.Now + " " + strCurrentThreadName + " " + SoursePath + " 第" + ImgNum + "张加水印成功"); break; case "thread4": Log.LogInfo(strCurrentThreadName, DateTime.Now + " " + strCurrentThreadName + " " + SoursePath + " 第" + ImgNum + "张加水印成功"); break; case "thread5": Log.LogInfo(strCurrentThreadName, DateTime.Now + " " + strCurrentThreadName + " " + SoursePath + " 第" + ImgNum + "张加水印成功"); break; case "thread6": Log.LogInfo(strCurrentThreadName, DateTime.Now + " " + strCurrentThreadName + " " + SoursePath + " 第" + ImgNum + "张加水印成功"); break; } //更新Shoes_Base信息 UpdateTable.UpdateShoes_Base(cp, ImgId); //加三点信息 atp.ImageWriteThreePoints(ss, TargePath); } //释放资源 ImageMark.Dispose(); } //释放资源 imgPhoto.Dispose(); } } catch (Exception ex) { //失败日志 Log.LogInfo(Thread.CurrentThread.Name.ToString(), "ERROR "+DateTime.Now + " " + Thread.CurrentThread.Name.ToString() + " " + SoursePath + "加水印失败. " + ex.Message.ToString()); } } /// <summary> /// 保存JPG时用 /// </summary> /// <param name="mimeType"></param> /// <returns></returns> private static ImageCodecInfo GetCodecInfo(string mimeType) { ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders(); foreach (ImageCodecInfo ici in CodecInfo) { if (ici.MimeType == mimeType) return ici; } return null; } /// <summary> /// 保存为JPEG格式,支持压缩质量选项 /// </summary> /// <param name="bmp">生成的bitmap</param> /// <param name="FileName">保存目录</param> /// <param name="Qty">图片质量</param> /// <returns></returns> public static bool KiSaveAsJPEG(Bitmap bmp, string FileName, int Qty) { try { EncoderParameter p; EncoderParameters ps; ps = new EncoderParameters(1); p = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, Qty); ps.Param[0] = p; bmp.Save(FileName, GetCodecInfo("image/jpeg"), ps); return true; } catch { return false; } } }
前几天应公司要求,要求做一个给图片加水印的工具,开始用的单线程。但后来发现测试的图片有200G,几十万个图片,于是乎采用多线程。废话不说,直接上图