using Baidu.Aip.ImageSearch; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using DevExpress.XtraEditors.DXErrorProvider; using DevExpress.XtraEditors; using Lskj.Util; using Lskj.Core; using System.Data.SqlClient; using Lskj.Control.Model; using Lskj.Control; using Lskj.Business.Impl; using System.Drawing.Imaging; namespace Lskj.PictureComp { public partial class FrmMain : BaseForm { public FrmMain() { InitializeComponent(); Add_TextProvider.ValidationMode = ValidationMode.Auto; SetRequired(Add_TextProvider, PageAdd_Tag1, PageAdd_Tag2, PageAdd_Brief, PageAdd_picEdit); } #region 公有变量 /// /// 选择文件 /// public OpenFileDialog FileDialog; /// /// 右侧panel宽度 /// int panleWidth; /// /// 构造文本填写约束 /// DXValidationProvider Add_TextProvider = new DXValidationProvider(); /// /// 接口连接 /// public ImageSearch client; #endregion #region 事件 #region 窗体加载时 /// /// 说明:窗体加载时 /// 创建人:王一帆 /// 创建日期:2021-06-15 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The instance containing the event data. protected override void OnLoad(EventArgs e) { try { if (DBConfig.Instance.CreateConnection()) { DataTable systemTab = SqlHelper.ExecuteDataTable("select * from p_systemtab"); DataRow dataRow = systemTab != null && systemTab.Rows.Count > 0 ? systemTab.Rows[0] : null; string imageSearchApiKey = dataRow.Table.Columns.Contains("imageSearchApiKey") ? dataRow["imageSearchApiKey"] + "" : ""; string imageSearchSecretKey = dataRow.Table.Columns.Contains("imageSearchSecretKey") ? dataRow["imageSearchSecretKey"] + "" : ""; client = new Baidu.Aip.ImageSearch.ImageSearch(imageSearchApiKey, imageSearchSecretKey); if (!BaseImpl.HasExistsTable("p_PictureComptab")) { CreationPictureTable(); this.panel_right.HorizontalScroll.Visible = false;//设置禁止水平滚动条 } } else { MessageUtil.Show("数据初始化失败!"); } } catch (Exception ex) { string Message = ErrorMessage.PromptErrorMessage(ex); MessageUtil.Show(Message, ex.Message); } finally { Lskj.Control.Model.AutoSizeChange.ControllInitializeSize(this); } } #endregion #region 添加窗口图片点击事件 /// /// 说明:添加窗口图片点击事件 /// 创建人:唐德馨 /// 创建日期:2021-07-19 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The instance containing the event data. private void OnPageAddPicEdit_Click(object sender, EventArgs e) { PageAdd_picEdit.Image = null; PageAdd_Tag1.Text = null; PageAdd_Tag2.Text = null; PageAdd_Brief.Text = null; panel_right.Controls.Clear(); labelRightToP.Text = "返回结果"; try { FileDialog = new OpenFileDialog(); FileDialog.Filter = "Picture(*.jpg,*.png,*.jpeg,*.bmp,*.gif)|*.jpg;*.png;*.jpeg;*.bmp|All files(*.*)|*.*"; if (FileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Image image = Image.FromFile(FileDialog.FileName); Bitmap bm = new Bitmap(image, PageAdd_picEdit.Width, PageAdd_picEdit.Height); this.PageAdd_picEdit.Image = bm; image.Dispose(); } } catch (Exception ex) { DevExpress.XtraEditors.LabelControl lable_ShowResult = new DevExpress.XtraEditors.LabelControl(); lable_ShowResult.Parent = panel_right; lable_ShowResult.Text = ex.ToString(); string Message = ErrorMessage.PromptErrorMessage(ex); //MessageUtil.Show(Message,ex.Message); } } #endregion #region 添加窗口确认按钮点击事件 /// /// 说明:添加窗口确认按钮点击事件 /// 创建人:唐德馨 /// 创建日期:2021-07-19 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The instance containing the event data. private void OnPageAddBtnCheck_Click(object sender, EventArgs e) { WaitForm.ShowForm(); try { if (Add_TextProvider.Validate()) { var image = File.ReadAllBytes(FileDialog.FileName); var options = new Dictionary(); options.Add("brief", PageAdd_Brief.Text); options.Add("tags", string.Format("{0},{1}", PageAdd_Tag1.Text, PageAdd_Tag2.Text)); JObject result = client.SimilarAdd(image, options); if (result.ContainsKey("error_code")) { switch (result["error_code"].ToString()) { case "216681": CreateErrorForm("添加失败!", global::Lskj.PictureComp.Properties.Resources.ErrorImg, "完全相同的图片不能重复入库!"); break; case "216202": CreateErrorForm("添加失败!", global::Lskj.PictureComp.Properties.Resources.ErrorImg, "上传的图片大小错误,请重新上传图片!"); break; } } else { string insertField = "pic_contsign,pic_brief,pic_tag1,pic_tag2,picture"; string insertValues = string.Format("'{0}','{1}','{2}','{3}',@Picture", result["cont_sign"].ToString(), PageAdd_Brief.Text, PageAdd_Tag1.Text, PageAdd_Tag2.Text); FileStream fs = new FileStream(FileDialog.FileName, FileMode.Open); BinaryReader br = new BinaryReader(fs); Byte[] byData = br.ReadBytes((int)fs.Length); fs.Close(); SqlParameter[] cmdParams = new SqlParameter[] { new SqlParameter("@Picture",SqlDbType.Binary,byData.Length), }; cmdParams[0].Value = byData; SqlHelper.ExecuteNonQuery(CommandType.Text, string.Format("insert into p_PictureComptab ({0}) values ({1})", insertField, insertValues), cmdParams); CreateErrorForm("添加成功!", global::Lskj.PictureComp.Properties.Resources.RightImg); } } } catch (Exception ex) { CreateErrorForm("添加失败!", global::Lskj.PictureComp.Properties.Resources.ErrorImg); string Message = ErrorMessage.PromptErrorMessage(ex); //MessageUtil.Show(Message,ex.Message); } WaitForm.HideForm(); } #endregion #region 添加窗口清除按钮点击事件 /// /// 说明:添加窗口清除按钮点击事件 /// 创建人:唐德馨 /// 创建日期:2021-07-19 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The instance containing the event data. private void OnPageAddBtnClear_Click(object sender, EventArgs e) { try { PageAdd_picEdit.Image = null; PageAdd_Tag1.Text = null; PageAdd_Tag2.Text = null; PageAdd_Brief.Text = null; } catch (Exception ex) { string Message = ErrorMessage.PromptErrorMessage(ex); MessageUtil.Show(Message, ex.Message); } } #endregion #region 搜索窗口图片点击事件 /// /// 说明:搜索窗口图片点击事件 /// 创建人:唐德馨 /// 创建日期:2021-07-19 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The instance containing the event data. private void OnPageSelectPicEdit_Click(object sender, EventArgs e) { panleWidth = this.panel_right.Width;//获取panel宽度 FileDialog = new OpenFileDialog(); FileDialog.Filter = "Picture(*.jpg,*.png,*.jpeg,*.bmp,*.gif)|*.jpg;*.png;*.jpeg;*.bmp|All files(*.*)|*.*"; if (FileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { PageSelect_picEdit.Image = null; panel_right.Controls.Clear(); Image image = Image.FromFile(FileDialog.FileName); Bitmap bitmap_File = new Bitmap(image, PageSelect_picEdit.Width, PageSelect_picEdit.Height); this.PageSelect_picEdit.Image = bitmap_File; image.Dispose(); WaitForm.ShowForm(); try { byte[] image_read = File.ReadAllBytes(FileDialog.FileName); Dictionary options = new Dictionary(); JObject result; if (PageSelect_tag1.Text != "" && PageSelect_tag2.Text != "") { options.Add("tags", string.Format("{0},{1}", PageSelect_tag1.Text, PageSelect_tag2.Text)); options.Add("tag_logic", "0"); result = client.SimilarSearch(image_read, options); } else { result = client.SimilarSearch(image_read); } List result_list = result["result"].ToList(); if (result_list.Count > 10) { result_list.RemoveRange(10, result_list.Count - 10); } List col_list = new List() { "brief", "score", "cont_sign" }; DataTable table = new DataTable();//转换结果数据为datatable table.Columns.Add("brief", typeof(string)); table.Columns.Add("score", typeof(double)); table.Columns.Add("cont_sign", typeof(string)); foreach (JObject resultRow in result_list) { DataRow row = table.NewRow(); row["brief"] = (string)resultRow["brief"]; row["score"] = (double)resultRow["score"]; row["cont_sign"] = (string)resultRow["cont_sign"]; table.Rows.Add(row); } string selectValue = ""; if (result_list.Count <= 10) { for (int i = 0; i < result_list.Count; i++) { selectValue += "'" + (result_list[i] as JObject)["cont_sign"].ToString() + "'" + ','; } } else { for (int i = 0; i < 10; i++) { selectValue += "'" + (result_list[i] as JObject)["cont_sign"].ToString() + "'" + ','; } } DataTable selectTable = SqlHelper.ExecuteDataTable(string.Format("select * from p_PictureComptab where pic_contsign in ({0})", selectValue.TrimEnd(','))); Color checkImageColor = GetImageAverageColor(bitmap_File);//获取当前选择图片的主颜色 foreach (DataRow tableRow in table.Rows) { DataRow[] rows = selectTable.Select(string.Format("pic_contsign = '{0}'", tableRow["cont_sign"].ToString())); if (rows.Length > 0) { MemoryStream memoryStream = new MemoryStream(rows[0]["picture"] as byte[]); Image _Image = Image.FromStream(memoryStream); Bitmap bitmap_read = new Bitmap(_Image); Color ImageColor = GetImageAverageColor(bitmap_read); double colorComp = 1 - getColorComp(checkImageColor, ImageColor) / (double)(Math.Sqrt(255 * 255 * 3)) + 0.01; tableRow["score"] = (double)tableRow["score"] + colorComp; } } DataView dv = table.DefaultView; dv.Sort = "score DESC"; table = dv.ToTable(); int left = 10; int top = 5; int num = 1; foreach (DataRow row in table.Rows) { DataRow[] rows = selectTable.Select(string.Format("pic_contsign = '{0}'", row["cont_sign"].ToString())); if (rows.Length > 0) { control_ShowPic control_ShowPic = new control_ShowPic(); control_ShowPic.textEdit_sign.Text = row["cont_sign"].ToString(); control_ShowPic.textEdit_brief.Text = row["brief"].ToString(); control_ShowPic.textEdit_score.Text = num.ToString();//((decimal)item["score"]).ToString("0.##%"); control_ShowPic.textEdit_class1.Text = rows[0]["pic_tag1"].ToString(); control_ShowPic.textEdit_class2.Text = rows[0]["pic_tag2"].ToString(); control_ShowPic.picName = control_ShowPic.textEdit_brief.Text; control_ShowPic.pic_show.Tag = rows[0]["picture"]; MemoryStream memoryStream = new MemoryStream(rows[0]["picture"] as byte[]); Image _Image = Image.FromStream(memoryStream); Bitmap bitmap_read = new Bitmap(_Image, control_ShowPic.pic_show.Width, control_ShowPic.pic_show.Height); control_ShowPic.picShowClickEventHandler picShowClickEvent = null; picShowClickEvent += new control_ShowPic.picShowClickEventHandler(createPictureForm); control_ShowPic.SetClickEvent(picShowClickEvent); _Image.Dispose(); control_ShowPic.pic_show.Image = bitmap_read; if (left + control_ShowPic.Width > panleWidth) { top += control_ShowPic.Height; left = 10; } if (left == 10) { control_ShowPic.Left = left; control_ShowPic.Top = top; panel_right.Controls.Add(control_ShowPic); left += control_ShowPic.Width + 10; } else { control_ShowPic.Top = top; control_ShowPic.Left = left; panel_right.Controls.Add(control_ShowPic); left += control_ShowPic.Width + 10; } num++; } } } catch (Exception ex) { CreateErrorForm("搜索失败!", global::Lskj.PictureComp.Properties.Resources.ErrorImg); string Message = ErrorMessage.PromptErrorMessage(ex); //MessageUtil.Show(Message,ex.Message); } finally { WaitForm.HideForm(); } } } #endregion\ #endregion #region 方法 #region 判断数据库中是否存在表 /// /// 说明:判断数据库中是否存在默认消息记录表 /// 创建人:唐德馨 /// 创建日期:2021-07-19 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// DataTable. public static void CreationPictureTable() { string sqlValue = string.Format(@"Create Table p_PictureComptab -- 图片筛选表 ( pic_contsign varchar(50) NOT NULL primary key, pic_brief varchar(50) NOT NULL, pic_tag1 int NULL, pic_tag2 int NULL, picture image NULL, )"); SqlHelper.ExecuteNonQuery(sqlValue); } #endregion #region 添加文本框填写规则 /// /// 添加文本框填写规则 /// /// /// public static void SetRequired(DXValidationProvider validationProvider, params BaseEdit[] param) { //实例化一个必填规则,错误提示为:该字段不能为空 ConditionValidationRule required = new ConditionValidationRule("RequiredRule", ConditionOperator.IsNotBlank) { ErrorText = "该字段不能为空" }; for (int i = 0; i < param.Length; i++) { //给控件对象设置规则 validationProvider.SetValidationRule(param[i], required); //设置文本显示位置 validationProvider.SetIconAlignment(param[i], ErrorIconAlignment.MiddleRight); } } #endregion #region 右侧panel创建正确或错误时的控件 public void CreateErrorForm(string text, Image image, string errorText = "") { panel_right.Controls.Clear(); ErrorForm errorForm = new ErrorForm(); errorForm.buttonError.BackgroundImage = image; //global::Lskj.PictureComp.Properties.Resources.ErrorImg; errorForm.errorLable.Text = text; panel_right.Controls.Add(errorForm); errorForm.Location = new Point((panel_right.Width - errorForm.Width) / 2, (panel_right.Height - errorForm.Height) / 2); Label label = new Label(); label.Text = errorText; label.Font = errorForm.errorLable.Font; label.TextAlign = ContentAlignment.MiddleCenter; label.AutoSize = true; panel_right.Controls.Add(label); label.Location = new Point((panel_right.Width - label.Width) / 2, (panel_right.Height - errorForm.Height) / 2 + errorForm.Height); } #endregion #region 图片点击放大方法 /// /// 说明:图片点击放大方法 /// 创建人:唐德馨 /// 创建日期:2021-07-19 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// DataTable. public void createPictureForm(string name, byte[] Byte) { Form Form = new Form(); Form.Text = name; Form.Width = 600; Form.Height = 600; //Form.FormBorderStyle = FormBorderStyle.None; Form.StartPosition = FormStartPosition.CenterScreen; DevExpress.XtraEditors.PictureEdit picEdit = new DevExpress.XtraEditors.PictureEdit(); picEdit.Dock = DockStyle.Fill; MemoryStream memoryStream = new MemoryStream(Byte); Image _Image = Image.FromStream(memoryStream); Bitmap bitmap_read = new Bitmap(_Image, Form.Width, Form.Height); _Image.Dispose(); picEdit.Image = bitmap_read; Form.Controls.Add(picEdit); Form.ShowDialog(); //picEdit.Click += OnPicEditClick; } #endregion #region 获取图片主颜色 /// /// 说明:获取图片主颜色 /// 创建人:唐德馨 /// 创建日期:2021-07-19 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// DataTable. public static unsafe Color GetImageAverageColor(Bitmap bitmap) { if (bitmap == null) { throw new ArgumentNullException("bitmap"); } int width = bitmap.Width; int height = bitmap.Height; Rectangle rect = new Rectangle(0, 0, width, height); try { BitmapData bitmapData = bitmap.LockBits( rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); byte* scan0 = (byte*)bitmapData.Scan0; int strideOffset = bitmapData.Stride - bitmapData.Width * 4; int sum = width * height; int a = 0; int r = 0; int g = 0; int b = 0; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { b += *scan0++; g += *scan0++; r += *scan0++; a += *scan0++; } scan0 += strideOffset; } bitmap.UnlockBits(bitmapData); a /= sum; r /= sum; g /= sum; b /= sum; return Color.FromArgb(255, r, g, b); } catch { return Color.FromArgb(127, 127, 127); } } #endregion #region 获取两张图片主颜色相似度 /// /// 说明:获取两张图片主颜色相似度 /// 创建人:唐德馨 /// 创建日期:2021-07-19 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 public double getColorComp(Color a, Color b) { double result = Math.Sqrt((a.R - b.R) * (a.R - b.R) + (a.G - b.G) * (a.G - b.G) + (a.B - b.B) * (a.B - b.B)); return result; } #endregion #endregion } }