using System; using System.Drawing; using System.Drawing.Drawing2D; 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 { /// /// 图片帮助类 /// 创建人:赵耀 /// 创建时间: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(); bitmap.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, 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 SaveUIToImage(FrameworkElement ui, string filePathName, int width, int height, int ImgWidth, int ImgHeight) { try { //在位图中呈现UI元素 RenderTargetBitmap bmp = new RenderTargetBitmap(width, height, PrimaryScreen.DpiX, PrimaryScreen.DpiY, PixelFormats.Pbgra32); bmp.Render(ui); BitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(bmp)); if (ImgWidth > 0) { Bitmap Img = new Bitmap(ImgWidth, ImgHeight); try { MemoryStream memoryStream = new MemoryStream(); encoder.Save(memoryStream); //System.Drawing.Image img = System.Drawing.Image.FromStream(memoryStream); Bitmap bit = new Bitmap(memoryStream); try { Graphics g = Graphics.FromImage(Img); //g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.DrawImage(bit, new Rectangle(0, 0, ImgWidth, ImgHeight), new Rectangle(0, 0, (int)bit.Width, (int)bit.Height), GraphicsUnit.Pixel); g.Dispose(); } catch { Img = bit; } new Thread(new ThreadStart(new Action(() => { Img.Save(filePathName); //Bitmap bitmap = CutImageWhitePart(Img); //FileToolsCommon.DeleteFile(filePathName); //bitmap.Save(filePathName); //bitmap.Dispose(); Img.Dispose(); bit.Dispose(); }))).Start(); } catch (Exception ex) { } } else { System.IO.FileStream fs = new System.IO.FileStream(filePathName, System.IO.FileMode.Create); encoder.Save(fs); fs.Close(); //MemoryStream memoryStream = new MemoryStream(); //encoder.Save(memoryStream); //Bitmap bit = new Bitmap(memoryStream); //bit.Save(filePathName); //bit.Dispose(); //using (FileStream tFileStream = new FileStream(filePathName,FileMode.Create, FileAccess.Write)) //{ // PngBitmapEncoder tPngBitmapEncoder = new PngBitmapEncoder(); // tPngBitmapEncoder.Interlace = PngInterlaceOption.On; // tPngBitmapEncoder.Frames.Add(BitmapFrame.Create(bmp)); // tPngBitmapEncoder.Save(tFileStream); // tFileStream.Close(); //} } } catch (Exception ex) { LogHelper.WriteErrLog("【UI生成图片】(SaveUIToImage)" + ex.Message, ex); //Console.WriteLine(ex.Message); } } #endregion #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 } }