C# winform 图片管理系统小结

问题1:如何展示图片以及如何选中DataGridView中展示的图片对象。

问题描述:后端功能函数返回的结果是List。展示图片的方式是:遍历所有后端返回的表情对象,按路径将表情存入imageList组件,再将imageList中的图片展示到DataGridView的单元格中。这样在选中单元格时,选中的不是Emoji对象,而是图片本身。

解决方案:设置一个静态变量public static List emojiList = new List();用来保存当前界面中显示的图片对应的对象。界面在初始化时规定好了一共展示多少行row多少列col,当前行r、列c索引和emojiList下标的对应关系为:
location = r * col + c;

展示图片的函数:

public void ShowEmojis(List<Emoji> emojis)
        {
            //清空图片数据
            imageList.Images.Clear();
            for (int r = 0; r < row; r++)
            {
                for (int c = 0; c < col; c++)
                {
                    this.dataGridViewImage[c, r].Value = null;
                }
            }
            //防止图片失真
            this.imageList.ColorDepth = ColorDepth.Depth32Bit;
            //当数据库图片不为空时,将图片加入imageList

            if (emojis.Count != 0)
            {
                foreach (Emoji e in emojis)
                {
                    if (e.Path != "")
                    {
                        try
                        {
                            this.imageList.Images.Add(System.Drawing.Image.FromFile(e.Path));
                        }
                        catch (System.IO.FileNotFoundException) { }
                    }
                }
                //Console.WriteLine("real:" + realcount+"emojicount:"+emojis.Count);
                
                //展示图片
                int count = 0;
                for (int r = 0; r < row; r++)
                {
                    for (int c = 0; c < col; c++)
                    {
                        if (count < imageList.Images.Count)
                        {
                            this.dataGridViewImage[c, r].Value = imageList.Images[count++];

                        }
                        else return;
                    }
                }
            }
            this.Refresh();
        }

问题2:拖拽添加图片效果的实现。

解决方案:当前窗口的DragDrop和DragEnter委托分别订阅两个自定义函数:
DragDrop += AddForm_DragDrop;
DragEnter += AddForm_DragEnter;

自定义函数如下:

private void AddForm_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effect = DragDropEffects.Link;
            else e.Effect = DragDropEffects.None;
        }
private void AddForm_DragDrop(object sender, DragEventArgs e)
        {
			//得到路径
            string path = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
			//显示图片
			this.pictureBox1.Image=Image.FromFile(path);
            //接着这里调用OCR
			… …
			//将信息填充进文本框
  			… …
        }

问题3:鼠标悬停显示图片对象信息

解决方案:难点在于:鼠标所在位置到DataGridView中单元格行列的映射。无法鼠标悬停时选中Emoji对象,因此无法展示图片数据。似乎没有好的解决方案。所以最后放弃了鼠标悬停显示图片信息,转而在鼠标左键点击图片选中图片对象时在当前鼠标所在位置显示ToolTip组件,展示图片信息。(ToolTip展示方式为:1.绑定到组件 2.绑定到当前位置。单元格不是组件,因此在鼠标所在位置显示ToolTip)

问题4:右键显示选择菜单

解决方案:使用ContextMenuStrip控件,右键选中的条件为:
e.Button == MouseButtons.Right
然后再鼠标当前位置显示ContextMenuStrip控件。

			//鼠标右键显示菜单
            if (e.Button == MouseButtons.Right)
            {
                int r = dataGridViewImage.CurrentCell.RowIndex;
                int c = dataGridViewImage.CurrentCell.ColumnIndex;
                int location = r * col + c;
                if (location < emojiList.Count)
                {
                    emojiSelected = emojiList[location];
                    cmsRightClick.Show(MousePosition);
                }
            }

问题5:图片来源

知乎api

URL参数:
文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。

参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。

锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分

问题6:调用OCR文字识别api

解决方案:图片需要经过base64和Url编码,并转换成字节流发送至服务器。主要代码如下:

  public static String getOcrResult(string path)
        {
            //access_token要定期换
            string url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general?access_token="+ getAccessToken();
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "post";
            request.KeepAlive = true;

            string base64 = getFileBase64(path);
            String str = "image=" + HttpUtility.UrlEncode(base64);
            Encoding encoding = Encoding.UTF8;
            byte[] buffer = encoding.GetBytes(str);
            request.ContentLength = buffer.Length;
            request.GetRequestStream().Write(buffer, 0, buffer.Length);

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
            string result = reader.ReadToEnd();
           //处理服务器返回结果得到最后的文字识别结果
			… …
        }
private static string getFileBase64(string path)
        {
            FileStream filestream = new FileStream(path, FileMode.Open);
            byte[] arr = new byte[filestream.Length];
            filestream.Read(arr, 0, (int)filestream.Length);
            string base64 = Convert.ToBase64String(arr);
            filestream.Close();
            return base64;
        }

你可能感兴趣的:(C#)