using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Text; using System.Threading; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; namespace Common.system { using XHWK.WKTool.system; /// /// 图片帮助类 创建人:赵耀 创建时间:2018年11月1日 /// public class ImageHelper { /// /// 通过FileStream 来打开文件,这样就可以实现不锁定Image文件,到时可以让多用户同时访问Image文件 /// /// 图片位置 /// public static Bitmap ReadBitmapFile(string path) { try { if (File.Exists(path)) { FileStream fs = File.OpenRead(path); //OpenRead int filelength = 0; filelength = (int)fs.Length; //获得文件长度 byte[] image = new byte[filelength]; //建立一个字节数组 fs.Read(image, 0, filelength); //按字节流读取 System.Drawing.Image result = System.Drawing.Image.FromStream(fs); fs.Close(); Bitmap bit = new Bitmap(result); return bit; } else { return null; } } catch (Exception) { return null; } } /// /// 通过FileStream 来打开文件,这样就可以实现不锁定Image文件,到时可以让多用户同时访问Image文件 /// /// 图片位置 /// public static Image ReadImageFile(string path) { try { if (File.Exists(path)) { FileStream fs = File.OpenRead(path); //OpenRead int filelength = 0; filelength = (int)fs.Length; //获得文件长度 byte[] image = new byte[filelength]; //建立一个字节数组 fs.Read(image, 0, filelength); //按字节流读取 System.Drawing.Image result = System.Drawing.Image.FromStream(fs); fs.Close(); return result; } else { return null; } } catch (Exception) { return null; } } /// /// 通过FileStream 来打开文件,这样就可以实现不锁定Image文件,到时可以让多用户同时访问Image文件 /// /// 图片位置 /// public static BitmapImage ReadBitmapImageFile(string path) { BitmapImage bitmap = new BitmapImage(); try { using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(path))) { bitmap = new BitmapImage { DecodePixelHeight = 100 }; bitmap.BeginInit(); bitmap.CacheOption = BitmapCacheOption.OnLoad;//设置缓存模式 bitmap.StreamSource = ms;//通过StreamSource加载图片 bitmap.EndInit(); bitmap.Freeze(); } return bitmap; } catch (Exception) { return null; } } #region 获取RGB private static Bitmap _Bitmap = null; private static StringBuilder sb = new StringBuilder(); public static string GetRGB(int x, int y) { sb = new StringBuilder(); try { System.Drawing.Color color = _Bitmap.GetPixel(x, y); sb.Append("RGB:("); sb.Append(color.R.ToString()); sb.Append(","); sb.Append(color.G.ToString()); sb.Append(","); sb.Append(color.B.ToString()); sb.Append(")"); } catch (Exception ex) { LogHelper.WriteErrLog("ImageHelper(GetRGB)" + ex.Message, ex); } return sb.ToString(); } #endregion 获取RGB #region 截图统一方法 /// /// 截图通用方法 创建人:赵耀 创建时间:2020年8月11日 /// /// 截图的区域,设置new Rectangle(0, 0, 0, 0)为截全屏 /// 图片存储路径,为空或null则保存到临时文件夹 /// 是否返回图片 /// 图片 /// 压缩等级,0到100,0 最差质量,100 最佳 /// public static bool GetScreenshot(Rectangle ScreenSize, string ImageSavePath, long level = -1) { try { System.Drawing.Size bounds = PrimaryScreen.DESKTOP; if (string.IsNullOrEmpty(ImageSavePath)) { ImageSavePath = GetTempImagePath();//如果为空则指定临时存储路径 } double scaleWidth = (bounds.Width * 1.0) / SystemParameters.PrimaryScreenWidth; double scaleHeight = (bounds.Height * 1.0) / SystemParameters.PrimaryScreenHeight; int width = bounds.Width; int height = bounds.Height; if (ScreenSize.Size != new System.Drawing.Size(0, 0)) { width = (int)(ScreenSize.Size.Width * scaleWidth); height = (int)(ScreenSize.Size.Height * scaleHeight); } int l = (int)(ScreenSize.X * scaleWidth); int t = (int)(ScreenSize.Y * scaleHeight); if (_Bitmap != null) { _Bitmap.Dispose(); } _Bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); using (Graphics g = Graphics.FromImage(_Bitmap)) { g.CopyFromScreen(l, t, 0, 0, _Bitmap.Size, CopyPixelOperation.SourceCopy); Compress(_Bitmap, ImageSavePath, level); } GC.Collect(); return true; } catch (Exception ex) { LogHelper.WriteErrLog("【截图】(GetBitmapSource)截图失败," + ex.Message, ex); return false; } } /// /// 截图通用方法 创建人:赵耀 创建时间:2020年8月11日 /// /// 截图的区域,设置new Rectangle(0, 0, 0, 0)为截全屏 /// 图片存储路径,为空或null则保存到临时文件夹 /// 是否返回图片 /// 图片 /// 压缩等级,0到100,0 最差质量,100 最佳 /// public static bool GetScreenshot(Rectangle ScreenSize, string ImageSavePath, bool IsRetImg, out BitmapImage bitmapimg, long level = -1) { bitmapimg = null; try { System.Drawing.Size bounds = PrimaryScreen.DESKTOP; if (string.IsNullOrEmpty(ImageSavePath)) { ImageSavePath = GetTempImagePath();//如果为空则指定临时存储路径 } double scaleWidth = (bounds.Width * 1.0) / SystemParameters.PrimaryScreenWidth; double scaleHeight = (bounds.Height * 1.0) / SystemParameters.PrimaryScreenHeight; int width = bounds.Width; int height = bounds.Height; if (ScreenSize.Size != new System.Drawing.Size(0, 0)) { width = (int)(ScreenSize.Size.Width * scaleWidth); height = (int)(ScreenSize.Size.Height * scaleHeight); } int l = (int)(ScreenSize.X * scaleWidth); int t = (int)(ScreenSize.Y * scaleHeight); if (_Bitmap != null) { _Bitmap.Dispose(); } _Bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); using (Graphics g = Graphics.FromImage(_Bitmap)) { g.CopyFromScreen(l, t, 0, 0, _Bitmap.Size, CopyPixelOperation.SourceCopy); Compress(_Bitmap, ImageSavePath, level); } if (IsRetImg) { Uri uri = new Uri(ImageSavePath, UriKind.Absolute); bitmapimg = new BitmapImage(uri); } GC.Collect(); return true; } catch (Exception ex) { LogHelper.WriteErrLog("【截图】(GetBitmapSource)截图失败," + ex.Message, ex); return false; } } /// /// 获取临时图片保存位置 /// /// public static string GetTempImagePath() { TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0); string TempPath = FileToolsCommon.GetFileAbsolutePath("/temp/Screenshot/"); FileToolsCommon.CreateDirectory(TempPath); TempPath += Convert.ToInt64(ts.TotalMilliseconds).ToString() + ".jpg"; return TempPath; } #endregion 截图统一方法 #region 图片压缩 /// /// 图片压缩(降低质量以减小文件的大小) 创建人:赵耀 创建时间:2020年8月11日 /// /// 传入的Bitmap对象 /// 压缩后的图片保存路径 /// 压缩等级,-1为config配置的值,0到100,0 最差质量,100 最佳 public static void Compress(Bitmap srcBitMap, string destFile, long level) { if (level <= -1) { int ImageCompressionLevel = int.Parse(FileToolsCommon.GetConfigValue("ImageCompressionLevel")); level = ImageCompressionLevel; } Stream s = new FileStream(destFile, FileMode.Create); Compress(srcBitMap, s, level); s.Close(); } /// /// 图片压缩(降低质量以减小文件的大小) 创建人:赵耀 创建时间:2020年8月11日 /// /// 传入的Bitmap对象 /// 压缩后的Stream对象 /// 压缩等级,0到100,0 最差质量,100 最佳 public static void Compress(Bitmap srcBitmap, Stream destStream, long level) { ImageCodecInfo myImageCodecInfo; System.Drawing.Imaging.Encoder myEncoder; EncoderParameter myEncoderParameter; EncoderParameters myEncoderParameters; //获取表示jpeg编解码器的imagecodecinfo对象 myImageCodecInfo = GetEncoderInfo("image/jpeg"); myEncoder = System.Drawing.Imaging.Encoder.Quality; myEncoderParameters = new EncoderParameters(1); myEncoderParameter = new EncoderParameter(myEncoder, level); myEncoderParameters.Param[0] = myEncoderParameter; srcBitmap.Save(destStream, myImageCodecInfo, myEncoderParameters); } /// /// 获取解码器 创建人:赵耀 创建时间2020年8月11日 /// /// /// private static ImageCodecInfo GetEncoderInfo(string mimeType) { int j; ImageCodecInfo[] encoders; encoders = ImageCodecInfo.GetImageEncoders(); for (j = 0; j < encoders.Length; ++j) { if (encoders[j].MimeType == mimeType) { return encoders[j]; } } return null; } /// /// 压缩图片 -测试方法 待完善 暂无用 /// /// 原图片 /// 压缩后保存图片地址 /// 压缩质量(数字越小压缩率越高)1-100 /// 压缩后图片的最大大小 /// 是否是第一次调用 /// public static bool CompressImage(Bitmap _bitmap, string dFile, int flag = 90, int size = 300) { ////如果是第一次调用,原始图像的大小小于要压缩的大小,则直接复制文件,并且返回true //FileInfo firstFileInfo = new FileInfo(sFile); //if (sfsc == true && firstFileInfo.Length < size * 1024) //{ // firstFileInfo.CopyTo(dFile); // return true; //} //Image iSource = Image.FromFile(sFile); Image iSource = _bitmap; ImageFormat tFormat = iSource.RawFormat; int dHeight = iSource.Height / 2; int dWidth = iSource.Width / 2; int sW, sH; //按比例缩放 System.Drawing.Size tem_size = new System.Drawing.Size(iSource.Width, iSource.Height); if (tem_size.Width > dHeight || tem_size.Width > dWidth) { if ((tem_size.Width * dHeight) > (tem_size.Width * dWidth)) { sW = dWidth; sH = (dWidth * tem_size.Height) / tem_size.Width; } else { sH = dHeight; sW = (tem_size.Width * dHeight) / tem_size.Height; } } else { sW = tem_size.Width; sH = tem_size.Height; } Bitmap ob = new Bitmap(dWidth, dHeight); Graphics g = Graphics.FromImage(ob); g.Clear(System.Drawing.Color.WhiteSmoke); g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.DrawImage(iSource, new Rectangle((dWidth - sW) / 2, (dHeight - sH) / 2, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel); g.Dispose(); //以下代码为保存图片时,设置压缩质量 EncoderParameters ep = new EncoderParameters(); long[] qy = new long[1]; qy[0] = flag;//设置压缩的比例1-100 EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy); ep.Param[0] = eParam; try { ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders(); ImageCodecInfo jpegICIinfo = null; for (int x = 0; x < arrayICI.Length; x++) { if (arrayICI[x].FormatDescription.Equals("JPEG")) { jpegICIinfo = arrayICI[x]; break; } } if (jpegICIinfo != null) { if (flag > 0) { ob.Save(dFile, jpegICIinfo, ep);//dFile是压缩后的新路径 FileInfo fi = new FileInfo(dFile); if (fi.Length > 1024 * size) { flag -= 10; CompressImage(_bitmap, dFile, flag, size); } } //ob.Save(dFile, jpegICIinfo, ep); //FileInfo fi = new FileInfo(dFile); //bool IsAgain = false; //if (fi.Length > 1024 * size) //{ // fi.CopyTo(dFile + fi.Length); // fi.Delete(); // Bitmap newbitmap = ReadImageFile(dFile + fi.Length); // CompressImage(newbitmap, dFile, flag, size); // FileToolsCommon.DeleteFile(dFile + fi.Length); //} } else { ob.Save(dFile, tFormat); } return true; } catch { return false; } finally { iSource.Dispose(); ob.Dispose(); } } #endregion 图片压缩 #region 截屏指定UI控件 /// /// 保存图片 /// /// 需要截图的UI控件 /// 图片保存地址 命名 1.png /// 转换后高 /// 转换后高 public static void SaveUI(FrameworkElement ui, string filePathName, int ImgWidth, int ImgHeight) { Console.WriteLine("截图的路径为:" + filePathName); try { RenderTargetBitmap bmp = new RenderTargetBitmap( (int)ui.ActualWidth, (int)ui.ActualHeight, 1 / 96, 1 / 96, PixelFormats.Default ); bmp.Render(ui); BitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(bmp)); if (ImgWidth > 0) { MemoryStream memoryStream = new MemoryStream(); encoder.Save(memoryStream); Bitmap bit = new Bitmap(memoryStream, true); Bitmap Img = new Bitmap(bit, ImgWidth, ImgHeight); Img.Save(filePathName); Img.Dispose(); bit.Dispose(); memoryStream.Dispose(); } else { using (var stream = new FileStream(filePathName, FileMode.Create)) { encoder.Save(stream); } } } catch (Exception e) { Console.WriteLine(e.Message); } } public static void SaveUI2(FrameworkElement frameworkElement, string filePathName) { System.IO.FileStream fs = new System.IO.FileStream(filePathName, System.IO.FileMode.Create); RenderTargetBitmap bmp = new RenderTargetBitmap((int)frameworkElement.ActualWidth, (int)frameworkElement.ActualHeight, 1 / 96, 1 / 96, PixelFormats.Default); bmp.Render(frameworkElement); BitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(bmp)); encoder.Save(fs); fs.Close(); } public static Bitmap SaveUI2Bitmap(FrameworkElement frameworkElement, int width, int height) { using (MemoryStream outStream = new MemoryStream()) { RenderTargetBitmap bmp = new RenderTargetBitmap( (int)frameworkElement.ActualWidth, (int)frameworkElement.ActualHeight, 1 / 96, 1 / 96, PixelFormats.Default ); bmp.Render(frameworkElement); BitmapEncoder enc = new PngBitmapEncoder(); enc.Frames.Add(BitmapFrame.Create(bmp)); enc.Save(outStream); System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(outStream); return new Bitmap(bitmap, width, height); } } /// /// 截图转换成bitmap /// /// /// 默认控件宽度 /// 默认控件高度 /// 默认0 /// 默认0 /// public static Bitmap ToBitmap(FrameworkElement element, string filePathName, int width = 0, int height = 0, int x = 0, int y = 0) { if (width == 0) width = (int)element.ActualWidth; if (height == 0) height = (int)element.ActualHeight; var rtb = new RenderTargetBitmap(width, height, x, y, System.Windows.Media.PixelFormats.Default); rtb.Render(element); var bit = BitmapSourceToBitmap(rtb); //测试代码 DirectoryInfo d = new DirectoryInfo(System.IO.Path.Combine(Directory.GetCurrentDirectory(), "Cache")); if (!d.Exists) d.Create(); bit.Save(System.IO.Path.Combine(d.FullName, "控件截图.png")); return bit; } /// /// BitmapSource转Bitmap /// /// /// public static Bitmap BitmapSourceToBitmap(BitmapSource source) { return BitmapSourceToBitmap(source, source.PixelWidth, source.PixelHeight); } /// /// Convert BitmapSource to Bitmap /// /// /// public static Bitmap BitmapSourceToBitmap(BitmapSource source, int width, int height) { Bitmap bmp = null; try { System.Drawing.Imaging.PixelFormat format = System.Drawing.Imaging.PixelFormat.Format24bppRgb; /*set the translate type according to the in param(source)*/ switch (source.Format.ToString()) { case "Rgb24": case "Bgr24": format = System.Drawing.Imaging.PixelFormat.Format24bppRgb; break; case "Bgra32": format = System.Drawing.Imaging.PixelFormat.Format32bppPArgb; break; case "Bgr32": format = System.Drawing.Imaging.PixelFormat.Format32bppRgb; break; case "Pbgra32": format = System.Drawing.Imaging.PixelFormat.Format32bppArgb; break; } bmp = new Bitmap(width, height, format); BitmapData data = bmp.LockBits(new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), ImageLockMode.WriteOnly, format); source.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride); bmp.UnlockBits(data); } catch { if (bmp != null) { bmp.Dispose(); bmp = null; } } return bmp; } #endregion 截屏指定UI控件 #region 去掉白边 /// /// 裁剪图片(去掉白边) /// /// public static Bitmap CutImageWhitePart(Bitmap bmp) { //Bitmap bmp = new Bitmap(FilePath); //上左右下 int top = 0, left = 0, right = bmp.Width, bottom = bmp.Height; //寻找最上面的标线,从左(0)到右,从上(0)到下 for (int i = 0; i < bmp.Height; i++)//行 { bool find = false; for (int j = 0; j < bmp.Width; j++)//列 { System.Drawing.Color c = bmp.GetPixel(j, i); if (!IsWhite(c)) { top = i; find = true; break; } } if (find) { break; } } //寻找最左边的标线,从上(top位)到下,从左到右 for (int i = 0; i < bmp.Width; i++)//列 { bool find = false; for (int j = top; j < bmp.Height; j++)//行 { System.Drawing.Color c = bmp.GetPixel(i, j); if (!IsWhite(c)) { left = i; find = true; break; } } if (find) { break; } } //寻找最下边标线,从下到上,从左到右 for (int i = bmp.Height - 1; i >= 0; i--)//行 { bool find = false; for (int j = left; j < bmp.Width; j++)//列 { System.Drawing.Color c = bmp.GetPixel(j, i); if (!IsWhite(c)) { bottom = i; find = true; break; } } if (find) { break; } } //寻找最右边的标线,从上到下,从右往左 for (int i = bmp.Width - 1; i >= 0; i--)//列 { bool find = false; for (int j = 0; j <= bottom; j++)//行 { System.Drawing.Color c = bmp.GetPixel(i, j); if (!IsWhite(c)) { right = i; find = true; break; } } if (find) { break; } } if (right - left <= 0)//zxyceshi { //克隆位图对象的一部分。 System.Drawing.Rectangle cloneRect = new System.Drawing.Rectangle(left, top, 1, bottom - top); Bitmap cloneBitmap = bmp.Clone(cloneRect, bmp.PixelFormat); bmp.Dispose(); //cloneBitmap.Save(@"d:\123.png", ImageFormat.Png); return cloneBitmap; } else { //克隆位图对象的一部分。 System.Drawing.Rectangle cloneRect = new System.Drawing.Rectangle(left, top, right - left, bottom - top); Bitmap cloneBitmap = bmp.Clone(cloneRect, bmp.PixelFormat); bmp.Dispose(); //cloneBitmap.Save(@"d:\123.png", ImageFormat.Png); return cloneBitmap; } } /// /// 判断是否白色和纯透明色(10点的容差) /// public static bool IsWhite(System.Drawing.Color c) { //纯透明也是白色,RGB都为255为纯白 if (c.A < 10 || (c.R > 245 && c.G > 245 && c.B > 245)) { return true; } return false; } #endregion 去掉白边 } public class SaveImageModel { public string FilePath { get; set; } public BitmapEncoder encoder { get; set; } //public RenderTargetBitmap bmp { get; set; } } public class SaveModel { public int ImgWidth { get; set; } public int ImgHeight { get; set; } public BitmapEncoder encoder { get; set; } public string filePathName { get; set; } public RenderTargetBitmap bmp { get; set; } } }