using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Text; 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; filelength = (int)fs.Length; //获得文件长度 byte[] image = new byte[filelength]; //建立一个字节数组 // ReSharper disable once MustUseReturnValue 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; filelength = (int)fs.Length; //获得文件长度 byte[] image = new byte[filelength]; //建立一个字节数组 // ReSharper disable once MustUseReturnValue 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; 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; 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.Logerror.Error("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.Logerror.Error("【截图】(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.Logerror.Error("【截图】(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) { //获取表示jpeg编解码器的imagecodecinfo对象 ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/jpeg"); System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality; EncoderParameters myEncoderParameters = new EncoderParameters(1); EncoderParameter 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 mbitmap, 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 = mbitmap; ImageFormat tFormat = iSource.RawFormat; int dHeight = iSource.Height / 2; int dWidth = iSource.Width / 2; int sW, sH; //按比例缩放 System.Drawing.Size temSize = new System.Drawing.Size(iSource.Width, iSource.Height); if (temSize.Width > dHeight || temSize.Width > dWidth) { if ((temSize.Width * dHeight) > (temSize.Width * dWidth)) { sW = dWidth; sH = (dWidth * temSize.Height) / temSize.Width; } else { sH = dHeight; sW = (temSize.Width * dHeight) / temSize.Height; } } else { sW = temSize.Width; sH = temSize.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( mbitmap, dFile, flag, size ); } } } 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, 96, 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, 96, 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, 96, 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); Bitmap 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; } } }