using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Text; using System.Threading.Tasks; using OTSIncAReportGraph.Class; using System.Runtime.InteropServices; using System.IO; using OpenCvSharp; namespace OTSIncAReportGraph.Class { /// /// 相关图表绘制函数统一封装类 /// static class DrawFunction { [DllImport("gdi32.dll")] public static extern System.UInt32 GetPixel(IntPtr hdc, int xPos, int yPos); /// /// 将一个byte的数组转换为8bit灰度位图 /// /// 数组 /// 图像宽度 /// 图像高度 /// 位图 public static Bitmap ToGrayBitmap(byte[] data, int width, int height) { //// 申请目标位图的变量,并将其内存区域锁定 Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed); //// BitmapData这部分内容 需要 using System.Drawing.Imaging; BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); //// 获取图像参数 // 扫描线的宽度 //int stride = bmpData.Stride; // 显示宽度与扫描线宽度的间隙 int offset = width - width; // 获取bmpData的内存起始位置 IntPtr iptr = bmpData.Scan0; // 用stride宽度,表示这是内存区域的大小 int scanBytes = width * height; //// 下面把原始的显示大小字节数组转换为内存中实际存放的字节数组 int posScan = 0, posReal = 0;// 分别设置两个位置指针,指向源数组和目标数组 byte[] pixelValues = new byte[scanBytes]; //为目标数组分配内存 for (int x = 0; x < height; x++) { //// 下面的循环节是模拟行扫描 for (int y = 0; y < width; y++) { pixelValues[posScan++] = data[posReal++]; } posScan += offset; //行扫描结束,要将目标位置指针移过那段“间隙” } //// 用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中 System.Runtime.InteropServices.Marshal.Copy(pixelValues, 0, iptr, scanBytes); bmp.UnlockBits(bmpData); // 解锁内存区域 //// 下面的代码是为了修改生成位图的索引表,从伪彩修改为灰度 ColorPalette tempPalette; using (Bitmap tempBmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed)) { tempPalette = tempBmp.Palette; } for (int i = 0; i < 256; i++) { tempPalette.Entries[i] = Color.FromArgb(i, i, i); } bmp.Palette = tempPalette; //// 算法到此结束,返回结果 return bmp; } /// /// *有BUG*将图片缩放到目标宽高,该方法有问题,不应该继续使用,图像申缩存在不规则问题 /// /// /// /// /// public static Image pictureProcess(Image sourceImage, int targetWidth, int targetHeight) { int width;//图片最终的宽 int height;//图片最终的高 try { System.Drawing.Imaging.ImageFormat format = sourceImage.RawFormat; Bitmap targetPicture = new Bitmap(targetWidth, targetHeight); Graphics g = Graphics.FromImage(targetPicture); g.Clear(Color.White); //计算缩放图片的大小 if (sourceImage.Width > targetWidth && sourceImage.Height <= targetHeight) { width = targetWidth; height = (width * sourceImage.Height) / sourceImage.Width; } else if (sourceImage.Width <= targetWidth && sourceImage.Height > targetHeight) { height = targetHeight; width = (height * sourceImage.Width) / sourceImage.Height; } else if (sourceImage.Width <= targetWidth && sourceImage.Height <= targetHeight) { width = sourceImage.Width; height = sourceImage.Height; } else { width = targetWidth; height = (width * sourceImage.Height) / sourceImage.Width; if (height > targetHeight) { height = targetHeight; width = (height * sourceImage.Width) / sourceImage.Height; } } g.DrawImage(sourceImage, (targetWidth - width) / 2, (targetHeight - height) / 2, width, height); g.Dispose(); return targetPicture; } catch (Exception ex) { string str = ex.ToString(); } return null; } /// /// 根据传入的宽和高,取得当前对应显示的4:3的标准分辨率 /// /// public static Rectangle Get43ScaleResolving(int in_width, int in_height) { Rectangle rect_resolving = new Rectangle(); int width_min = 0; int height_min = 0; int width_max = 0; int height_max = 0; width_min = 1600; height_min = 1200; width_max = 2048; height_max = 1536; if ((in_width >= width_min && in_width < width_max) || (in_height >= height_min && in_height < height_max)) rect_resolving = new Rectangle(0, 0, width_min, height_min); width_min = 1400; height_min = 1050; width_max = 1600; height_max = 1200; if ((in_width >= width_min && in_width < width_max) || (in_height >= height_min && in_height < height_max)) rect_resolving = new Rectangle(0, 0, width_min, height_min); width_min = 1280; height_min = 1024; width_max = 1400; height_max = 1050; if ((in_width >= width_min && in_width < width_max) || (in_height >= height_min && in_height < height_max)) rect_resolving = new Rectangle(0, 0, width_min, height_min); width_min = 1024; height_min = 768; width_max = 1280; height_max = 1024; if ((in_width >= width_min && in_width < width_max) || (in_height >= height_min && in_height < height_max)) rect_resolving = new Rectangle(0, 0, width_min, height_min); width_min = 800; height_min = 600; width_max = 1024; height_max = 768; if ((in_width >= width_min && in_width < width_max) || (in_height >= height_min && in_height < height_max)) rect_resolving = new Rectangle(0, 0, width_min, height_min); width_min = 640; height_min = 480; width_max = 800; height_max = 600; if ((in_width >= width_min && in_width < width_max) || (in_height >= height_min && in_height < height_max)) rect_resolving = new Rectangle(0, 0, width_min, height_min); width_min = 320; height_min = 240; width_max = 640; height_max = 480; if ((in_width >= width_min && in_width < width_max) || (in_height >= height_min && in_height < height_max)) rect_resolving = new Rectangle(0, 0, width_min, height_min); width_min = 0; height_min = 0; width_max = 320; height_max = 240; if ((in_width >= width_min && in_width < width_max) || (in_height >= height_min && in_height < height_max)) rect_resolving = new Rectangle(0, 0, width_min, height_min); return rect_resolving; } /// /// [该方法效果正确,但速度上慢,淘汰掉],上下翻转 /// /// 原始图片 /// 原始图片的长度 /// 原始图片的高度 public static Bitmap RevPicUD(Bitmap mybm, int width, int height) { Bitmap bm = new Bitmap(width, height); int x, y, z; Color pixel; for (x = 0; x < width; x++) { for (y = height - 1, z = 0; y >= 0; y--) { pixel = mybm.GetPixel(x, y);//获取当前像素的值 bm.SetPixel(x, z++, Color.FromArgb(pixel.R, pixel.G, pixel.B));//绘图 } } return bm; } /// /// 实现计算的方法,就是输出个数字,然后向上寻找倍数,然后返回来根 /// /// /// public static int GetSquareRoot(int in_number) { int i_increase = 1; while (true) { //防止死循环 if (i_increase > 10000) return i_increase; int ls_i = i_increase * i_increase; if (in_number > ls_i) { //如果当前的数值已经大于平方数的话,那就继续下一次的平方 i_increase++; continue; } else { //如果已经小于平方数的话,那就说明已经找到了平方根,返回 return i_increase; } } } /// /// 根据传入的数字返回对应的颜色,范围1-17种颜色,挑出来比较谈的颜色为对比效果好看而挑选 /// /// /// public static Color GetColorByNumber(int number) { Color ret_color = new Color(); switch (number) { case 1: ret_color = Color.Blue; break; case 2: ret_color = Color.Brown; break; case 3: ret_color = Color.LimeGreen; break; case 13: ret_color = Color.Cyan; break; case 4: ret_color = Color.DarkBlue; break; case 5: ret_color = Color.Red; break; case 6: ret_color = Color.SaddleBrown; break; case 7: ret_color = Color.DimGray; break; case 8: ret_color = Color.Navy; break; case 9: ret_color = Color.Peru; break; case 10: ret_color = Color.Red; break; case 11: ret_color = Color.SeaGreen; break; case 12: ret_color = Color.MintCream; break; case 14: ret_color = Color.PaleTurquoise; break; case 15: ret_color = Color.SeaShell; break; case 16: ret_color = Color.Snow; break; case 17: ret_color = Color.WhiteSmoke; break; default: ret_color = Color.White; break; } return ret_color; } /// /// 获取一个自绘模仿进度条的bitemap对象,传入进度的值,0-100之间 /// /// /// public static Bitmap GetProcessBitmap(int process_value) { Bitmap bmp = new Bitmap(104, 30); //这里给104是为了左边和右边空出2个像素,剩余的100就是百分比的值 Graphics g = Graphics.FromImage(bmp); g.Clear(Color.White); //背景填白色 //g.FillRectangle(Brushes.Red, 2, 2, this.Press, 26); //普通效果 //填充渐变效果 SolidBrush drawBrush = new SolidBrush(Color.Black); g.FillRectangle(new System.Drawing.Drawing2D.LinearGradientBrush(new System.Drawing.Point(30, 2), new System.Drawing.Point(30, 30), Color.Red, Color.Gray), 2, 2, process_value, 26); g.DrawString(process_value.ToString(), new Font("宋体", 9), drawBrush, 50, 8); return bmp; } /// /// 获取一个自绘模仿进度条的bitemap对象,传入进度的值,0-100之间[重载可以自定设置背景色] /// /// /// /// public static Bitmap GetProcessBitmap(float process_value, Color back_color) { if (process_value < 0) process_value = 0; if (process_value > 100) process_value = 100; Bitmap bmp = new Bitmap(104, 30); //这里给104是为了左边和右边空出2个像素,剩余的100就是百分比的值 Graphics g = Graphics.FromImage(bmp); g.Clear(back_color); //背景填白色 //g.FillRectangle(Brushes.Red, 2, 2, this.Press, 26); //普通效果 //填充渐变效果 SolidBrush drawBrush = new SolidBrush(Color.Black); g.FillRectangle(new System.Drawing.Drawing2D.LinearGradientBrush(new System.Drawing.Point(30, 2), new System.Drawing.Point(30, 30), Color.Red, Color.Gray), 2, 2, process_value, 26); g.DrawString(process_value.ToString(), new Font("宋体", 9), drawBrush, 50, 8); return bmp; } /// /// [颜色:16进制转成RGB] /// /// 设置16进制颜色 [返回RGB] /// public static System.Drawing.Color colorHx16toRGB(string strHxColor) { try { if (strHxColor.Length == 0) {//如果为空 return System.Drawing.Color.FromArgb(0, 0, 0);//设为黑色 } else {//转换颜色 if (strHxColor.IndexOf('#') > -1) { //如果颜色格式是 #0000FF 格式的 return System.Drawing.Color.FromArgb(System.Int32.Parse(strHxColor.Substring(1, 2), System.Globalization.NumberStyles.AllowHexSpecifier), System.Int32.Parse(strHxColor.Substring(3, 2), System.Globalization.NumberStyles.AllowHexSpecifier), System.Int32.Parse(strHxColor.Substring(5, 2), System.Globalization.NumberStyles.AllowHexSpecifier)); } else { //如果颜色格式是 0000FF 格式的 return System.Drawing.Color.FromArgb(System.Int32.Parse(strHxColor.Substring(0, 2), System.Globalization.NumberStyles.AllowHexSpecifier), System.Int32.Parse(strHxColor.Substring(2, 2), System.Globalization.NumberStyles.AllowHexSpecifier), System.Int32.Parse(strHxColor.Substring(4, 2), System.Globalization.NumberStyles.AllowHexSpecifier)); } } } catch {//设为黑色 return System.Drawing.Color.FromArgb(0, 0, 0); } } /// /// 通过FileStream 来打开文件,这样就可以实现不锁定Image文件,到时可以让多用户同时访问Image文件 /// /// /// public static Bitmap ReadImageFile(string path) { if (!File.Exists(path)) { return null;//文件不存在 } 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; } //图片转成二进制 public static byte[] GetPictureData(string imagepath) { /**/ ////根据图片文件的路径使用文件流打开,并保存为byte[] FileStream FileStream = new FileStream(imagepath, FileMode.Open); byte[] byData = new byte[FileStream.Length]; FileStream.Read(byData, 0, byData.Length); FileStream.Close(); return byData; } /// /// 将image转成bytes /// /// /// public static byte[] ImageConvertToBytes(System.Drawing.Image in_img) { MemoryStream ms = new MemoryStream(); in_img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); return ms.ToArray(); } /// /// Resize图片 /// /// 原始Bitmap /// 新的宽度 /// 新的高度 /// 处理以后的图片 public static Bitmap KiResizeImage(Bitmap bmp, int newW, int newH) { try { Bitmap b = new Bitmap(newW, newH); Graphics g = Graphics.FromImage(b);                 // 插值算法的质量                 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel); g.Dispose(); return b; } catch { return null; } } public static Bitmap GetReZoomBitmap(Bitmap in_bp) { Mat src = OpenCvSharp.Extensions.BitmapConverter.ToMat(in_bp); Mat dst = new Mat(); Cv2.AdaptiveThreshold(src, dst, 255, AdaptiveThresholdTypes.MeanC, ThresholdTypes.Binary, 27, 25); //绝对缩放, Mat dst2 = new Mat(); int col = dst.Width;//获取原图像的大小 int rows = dst.Height; Cv2.Resize(dst, dst2, new OpenCvSharp.Size(4 * col, 4 * rows), 0, 0, InterpolationFlags.Cubic); return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(dst2); } } /// /// 获取当前桌面显示器相关信息,暂未考虑多显示器 /// static public class MyPrimaryScreen { #region Win32 API   [DllImport("user32.dll")] static extern IntPtr GetDC(IntPtr ptr); [DllImport("gdi32.dll")] static extern int GetDeviceCaps( IntPtr hdc, // handle to DC   int nIndex // index of capability   ); [DllImport("user32.dll", EntryPoint = "ReleaseDC")] static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc); #endregion #region DeviceCaps常量   const int HORZRES = 8; const int VERTRES = 10; const int LOGPIXELSX = 88; const int LOGPIXELSY = 90; const int DESKTOPVERTRES = 117; const int DESKTOPHORZRES = 118; #endregion #region 属性   ///    /// 获取屏幕分辨率当前物理大小   ///    public static System.Drawing.Size WorkingArea { get { IntPtr hdc = GetDC(IntPtr.Zero); System.Drawing.Size size = new System.Drawing.Size(); size.Width = GetDeviceCaps(hdc, HORZRES); size.Height = GetDeviceCaps(hdc, VERTRES); ReleaseDC(IntPtr.Zero, hdc); return size; } } ///    /// 当前系统DPI_X 大小 一般为96   ///    public static int DpiX { get { IntPtr hdc = GetDC(IntPtr.Zero); int DpiX = GetDeviceCaps(hdc, LOGPIXELSX); ReleaseDC(IntPtr.Zero, hdc); return DpiX; } } ///    /// 当前系统DPI_Y 大小 一般为96   ///    public static int DpiY { get { IntPtr hdc = GetDC(IntPtr.Zero); int DpiX = GetDeviceCaps(hdc, LOGPIXELSY); ReleaseDC(IntPtr.Zero, hdc); return DpiX; } } ///    /// 获取真实设置的桌面分辨率大小   ///    public static System.Drawing.Size DESKTOP { get { IntPtr hdc = GetDC(IntPtr.Zero); System.Drawing.Size size = new System.Drawing.Size(); size.Width = GetDeviceCaps(hdc, DESKTOPHORZRES); size.Height = GetDeviceCaps(hdc, DESKTOPVERTRES); ReleaseDC(IntPtr.Zero, hdc); return size; } } ///    /// 获取宽度缩放百分比   ///    public static float ScaleX { get { IntPtr hdc = GetDC(IntPtr.Zero); int t = GetDeviceCaps(hdc, DESKTOPHORZRES); int d = GetDeviceCaps(hdc, HORZRES); float ScaleX = (float)GetDeviceCaps(hdc, DESKTOPHORZRES) / (float)GetDeviceCaps(hdc, HORZRES); ReleaseDC(IntPtr.Zero, hdc); return ScaleX; } } ///    /// 获取高度缩放百分比   ///    public static float ScaleY { get { IntPtr hdc = GetDC(IntPtr.Zero); float ScaleY = (float)(float)GetDeviceCaps(hdc, DESKTOPVERTRES) / (float)GetDeviceCaps(hdc, VERTRES); ReleaseDC(IntPtr.Zero, hdc); return ScaleY; } } #endregion } }