C#のWinformを使用して、グラフィック認識OCRとスクリーンショット機能を実現します

序文

       オンラインで情報を確認すると、コピーしたい記事がたくさんありますが、制限がありますので、VIPを充電して消費し、コピーの許可を得ることができます。もちろん、充電せずにコピーしたい場合は方法がありません。私が最もよく使用するのは、QQソフトウェアを開き、コピーしたい記事のスクリーンショットを撮り、写真のテキストを抽出することです。

QQテキスト抽出機能

ここに写真の説明を挿入
       もちろん、面白い機能を見るたびに、その実装方法を勉強します。今日は時間があるのでちなみにWinformをレビューします私が最初にそれをしたとき、私は関連情報をオンラインでチェックしました。それらのほとんどは2つの方法を紹介します:

方法1:Asprise-OCRの実現。

方法2、Microsoft Office Document Imaging(Office 2007)コンポーネントの実装。

私もこれらの2つの方法を試しました。ただし、(方法1)は中国語をサポートしていませんが、(方法2)を実現するには、ユーザーがコンポーネントをダウンロードする必要があります。もちろん、APPを開発していて、それを使用する前に他のプラグインをダウンロードする必要がある場合、ユーザーエクスペリエンスが大幅に低下する可能性があります。そのため、これら2つの方法を放棄し、BaiduAIのOCRグラフィック認識インターフェイスを採用する必要がありました

実現アイデア

[1]メインフォームとスクリーンショットフォームの2つのフォームを作成します。
[2]メインフォームには、画像の読み込み、切り取り、またはローカル画像のプレビューを行うためのPictureBoxコントロールがあります。
[3]つまり、画像とテキストの認識という目標を達成するために、2種類あります。1つは、地元のテキストを含む写真を見つけることです。2はスクリーンショットです。
[4]スクリーンショットボタンをクリックすると、スクリーンショットフォームがすぐに呼び出され、現在のフォームHide()が非表示になります。スクリーンショットフォーム自体は半透明のフォームです。スクリーンショットプロセスで最も重要なことは、3つのステップに分かれていることです。
(1)マウスが押されたとき:MouseDownはスクリーンショットの開始を表し、マウスが押されたときの座標を記録します。
(2)マウスが動いたとき:MouseMoveがマウスを動かしている間、オフセット座標が記録されると同時に、GraphicsのFillRectangle()メソッドを使用して、マウスの動きの座標に従って長方形が塗りつぶされ、範囲がクリアされて完全な透明度が達成されます。スクリーンショットの領域を表します。
(3)マウスを離すと:MouseUpは現在の座標を記録し、スクリーンショットフォームを閉じ、メインフォームにスクリーンショットを生成するグラフィックツールのCopyFromScreen()メソッドを呼び出します。そして、メインフォームを表示します。スクリーンショットの終わりを表します。
[5]次に、スクリーンショットが生成されたら、PictureBoxのBackgroundImageの背景画像を設定します。
[6] PictureBoxにcontextMenuStripコントロールを追加します。右クリックすると、画像をコピーできます。Clipboard.SetImage()メソッドが使用されます。クリップボードにコピー。このようにして、クリップした画像を貼り付けることができる任意の場所にコピーできます。
[7]ボタンをクリックしてテキストを認識します。まず、Baidu AIオープンプラットフォームにアクセスして、グラフィック認識アプリケーションを申請し、関連するAPI_KEYとSECRET_KEYを取得する必要があります。client.GeneralBasic();の後、イメージパスバイナリファイルを読み取ります。つまり、IOファイルFile.ReadAllBytes(imagePath);のReadAllBytes()メソッドを使用するだけです。最後に、Baidu OCRグラフィック認識は、関連するJSON形式のデータを返します。TextBoxに値を割り当てるには、その値を解析する必要があります。次に、戻り形式に「words_result_num」があります。このフィールドは、結果データの行数を表す、簡単に言うことができます。次に、ループしても問題ありません。言うことはあまりありませんが、コードに移動してください。

データ戻り形式

{
  "log_id": xxxxxxxxxxxxxxxxxxxxx,
  "words_result_num": 11,
  "words_result": [
    {
      "words": "“OCR是英文 Optical Character Recognition的缩写,意思是光学字符识别"
    },
    {
      "words": "也可简单地称为文字识别,是文字自动输入的种方法。它通过扫描和摄像等"
    },
    {
      "words": "光学输入方式获取纸张上的文字图像信息,利用各种模式识别算法分析文字形"
    },
    {
      "words": "态特征可以将票据、报刊、书籍、文稿及其它印刷品转化为图像信息,再利用文"
    },
    {
      "words": "字识别技术将图像信息转化为可以使用的计算机翰入技术。可应用于银行票据、"
    },
    {
      "words": "大量文字资料、档案卷宗、文案的录入和处理领域。适合于银行、税务等行业大"
    },
    {
      "words": "量票据表格的自动扫描识别及长期存储。相对-般文本,通常以最终识别率、识"
    },
    {
      "words": "别速度、版面理解正确率及版面还原满意度4个方面作为OCR技术的评测依据」"
    },
    {
      "words": "而相对于表格及票据,通常以识别率或整张通过率及识别速度为测定OCR技术"
    },
    {
      "words": "的实用标准,随着人工智能的兴起,人们在追求让工作更简单化,OC识别技"
    },
    {
      "words": "术"
    }
  ]
}

実装手順

1:メインウィンドウインターフェイス

メインフォーム

メインインターフェイスコード

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.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Drawing.Imaging;
using System.Threading;


namespace ImageRecognition
{
    
    
    public partial class Mainform : Form
    {
    
    
        /// <summary>
        /// 声明当前窗体,用于截图完了之后调用
        /// </summary>
        public static Mainform currentForm = null;
        public string imagePath = "";
        public Mainform()
        {
    
    
            InitializeComponent();
            currentForm = this;
        }

    

        /// <summary>
        /// 点击浏览图片按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_imgpath_Click(object sender, EventArgs e)
        {
    
    
            openFileDialog1.ShowDialog();
            txt_imgpath.Text = openFileDialog1.FileName;
            pictureBox.BackgroundImage = Image.FromFile(txt_imgpath.Text);
            pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
        }
        
        /// <summary>
        /// 加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
    
    
        

        }
        
        /// <summary>
        /// 生成截图,截图完成并鼠标释放时调用
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public void GeneratingScreenshots(int x, int y, int width, int height)
        {
    
    
            try
            {
    
    
                pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
                Bitmap image; image = new Bitmap(width, height);
                Graphics g = Graphics.FromImage(image);
                //'截屏 CopyFromScreen,前两个参数表示截屏起点,第三和第四为绘制图像的起点。
                g.CopyFromScreen(x, y, 0, 0, new System.Drawing.Size(width, height));
                //当图片小于  pictureBox 控件的时候给他居中
                if (width < pictureBox.Width && height < pictureBox.Height)
                    pictureBox.BackgroundImageLayout = ImageLayout.Center;
                pictureBox.BackgroundImage = image;
            }
            catch (Exception ex)
            {
    
    
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 右击鼠标 点击复制图片时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 复制图片在剪贴板ToolStripMenuItem_Click(object sender, EventArgs e)
        {
    
    
            //判断 pictureBox 是否有图片 即判断是否已经截图
            if (pictureBox.BackgroundImage != null)      
            {
    
    
                //将图片已复制到剪贴板
                Clipboard.SetImage(pictureBox.BackgroundImage);
                MessageBox.Show("图片已复制到剪贴板", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        /// <summary>
        /// 点击截图按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Screenshot_Click(object sender, EventArgs e)
        {
    
    
            this.Hide();                                  //当前窗体隐藏
            Screenshot screenshot = new Screenshot();     //实例化截图窗体
            screenshot.ShowDialog();                      //显示截图窗体
        }

        /// <summary>
        /// 点击图文识别按钮的点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_BaiduOCR_Click(object sender, EventArgs e)
        {
    
    
            //百度图文识别应用的 API_KEY,以及 SECRET_KEY  ,可以登录去复制
            var API_KEY = "你的API_KEY";
            var SECRET_KEY = "你的SECRET_KEY";
            var client = new Baidu.Aip.Ocr.Ocr(API_KEY, SECRET_KEY);
            client.Timeout = 60000;  // 设置超时时间

            if (imagePath.IndexOf('.') == -1)
            {
    
    
                imagePath = txt_imgpath.Text;
            }
            else 
            {
    
    
                MessageBox.Show("您还未截图,或选择图片识别");
                return;
            }
            var image = File.ReadAllBytes(imagePath);
            try
            {
    
    
                //发送需要识别的图片
                var result = client.GeneralBasic(image);
                txt_result.Text = JsonGetStr(result.ToString());
            }
            catch (Exception ex)
            {
    
    
                txt_result.Text = ex.Message;
            }
        }

        /// <summary>
        /// 解析百度API返回的json格式扫描内容
        /// </summary>
        /// <param name="ReText"></param>
        /// <returns></returns>
        public string JsonGetStr(string ReText)
        {
    
    
            JObject obj = Newtonsoft.Json.Linq.JObject.Parse(ReText);
            string resMag = "";
            JToken record = obj["words_result"];
            JToken[] TrainInfoArr = record.ToArray();
            int arrLength = TrainInfoArr.Length;
            for (int i = 0; i < arrLength; i++)
            {
    
    
                resMag += TrainInfoArr[i]["words"].ToString();
            }
            return resMag;
        }

        private void 保存截图CtrlsToolStripMenuItem_Click(object sender, EventArgs e)
        {
    
    
            if (pictureBox.BackgroundImage != null)
            {
    
    
                SaveFileDialog saveFile = new SaveFileDialog();
                saveFile.DefaultExt = "png";
                saveFile.Filter = "Png Files|*.png";
                Random ranNum = new Random();
                saveFile.FileName = "XiaoGang" + ranNum.Next(1000, 9999);
                imagePath = saveFile.FileName;
                DialogResult dialogResult = saveFile.ShowDialog();
                if (dialogResult == System.Windows.Forms.DialogResult.OK)
                {
    
    
                    pictureBox.BackgroundImage.Save(saveFile.FileName, ImageFormat.Png);
                }
            }
        }

    }
}

スクリーンショットフォーム:コントロールをドラッグする必要はありません。次のプロパティを設定するだけです。

(1)Cursor属性は次のとおりです。Cross;マウスが上にあるときの十字形を表します。
(2)FormorderStyleプロパティは次のとおりです。なし。外観フォームは不要で、最小化、最大化、および閉じるボタンは表示されません。
(3)WindowStateプロパティは次のとおりです:最大化;ウィンドウは最大化されます;
(4)Optityプロパティは次のとおりです:50%;ウィンドウの透明度はスクリーンショットの完全に透明な領域と対照的に設定されます。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace ImageRecognition
{
    
    
    public partial class Screenshot : Form
    {
    
    
        
        int x, y, nowX, nowY, width, height;
        bool isMouthDown = false;
        Graphics g;

        /// <summary>
        /// 鼠标释放
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form2_MouseUp(object sender, MouseEventArgs e)
        {
    
    
            nowX = MousePosition.X + 1;
            nowY = MousePosition.Y + 1;
            this.Close();
            Mainform.currentForm.GeneratingScreenshots(x < nowX ? x : nowX, y < nowY ? y : nowY, width, height);
            Mainform.currentForm.Show();
        }

     
        /// <summary>
        /// 鼠标移动的时候
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form2_MouseMove(object sender, MouseEventArgs e)
        {
    
    
            if (isMouthDown)
            {
    
    
                width = Math.Abs(MousePosition.X - x);         //获取宽
                height = Math.Abs(MousePosition.Y - y);        //获取高
                g = CreateGraphics();                          //开始创建一个Graphics
                g.Clear(this.BackColor);                       //清空背景颜色
                //根据鼠标移动的坐标填充一个矩形
                g.FillRectangle(Brushes.CornflowerBlue, x < MousePosition.X ? x : MousePosition.X, y < MousePosition.Y ? y : MousePosition.Y, width + 1, height + 1);
            }
        }

        /// <summary>
        /// 鼠标按下的时候
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form2_MouseDown(object sender, MouseEventArgs e)
        {
    
    
            x = MousePosition.X;
            y = MousePosition.Y;
            isMouthDown = true;
        }

      
        public Screenshot()
        {
    
    
            InitializeComponent();
        }
    }
}

注:言及するのを忘れた場合は、必ずBaidu.Aip.Ocrを使用して追加してください。Baiduのグラフィック認識OCRリファレンスです。VisualStudioのプロジェクト管理Nugetパッケージを右クリックしてダウンロードできます

GU
xz

プロジェクト全体の操作ビデオ

Winform模倣qqスクリーンショット、OCRグラフィック認識

やっと

さて、今日の共有は終わりました!欠陥を指摘し、批判を誠実に受け入れることを歓迎します。もちろん、質問がある友達は以下にコメントすることができます。OCR Baiduグラフィック認識APIをわざわざ申請する必要がない場合は、私と個人的にチャットできます。楽しみのためにお貸しします。

仲良しのブログアドレスhttps://blog.csdn.net/weixin_43851854

おすすめ

転載: blog.csdn.net/WenRouDG/article/details/107852276