实现需求:
C#为后端代码,HTML为前端。
建立C#winform后端程序,内嵌HTML前端网页,后端读入图像,将图像传输到前端HTML显示,前端再返回后端显示成功信号。
实现平台:
Visual Studio 2017
google浏览器内核(注:用Visual Studio自带的WebBrowser也可以实现一样的需求,但是其自带的WebBrowser内核为IE7,兼容性不好,所以本文采用google的内核)
1、新建winform工程
2、安装内嵌google浏览器NuGet程序包
点击“项目”—》“管理NuGet程序包(N)”—》“浏览”,输入CefSharp.WinForms进行安装
点击“确定”
安装完成后工程路径下会多一个packages文件夹,对应的google浏览器库就在里面。
3、引用google内核
点击“引用”—》“添加引用”—》“浏览”—》“浏览”。添加我们第二步安装的库文件。
E:\Codes\VisualStudio\CSharp\test\packages\CefSharp.WinForms.85.3.130\CefSharp\x64\CefSharp.WinForms.dll
E:\Codes\VisualStudio\CSharp\test\packages\CefSharp.Common.85.3.130\CefSharp\x64\CefSharp.BrowserSubprocess.Core.dll
E:\Codes\VisualStudio\CSharp\test\packages\CefSharp.Common.85.3.130\CefSharp\x64\CefSharp.Core.dll
E:\Codes\VisualStudio\CSharp\test\packages\CefSharp.Common.85.3.130\CefSharp\x64\CefSharp.dll
4、添加按钮button1和openFileDialog1
5、在winform中添加代码(Emgucv的配置就不做介绍了)
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;
using CefSharp;
using CefSharp.WinForms;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using Emgu.CV.CvEnum;
using System.IO;
using System.Drawing.Imaging;
namespace test
{
public partial class Form1 : Form
{
public ChromiumWebBrowser browser;
public Form1()
{
InitializeComponent();
///设置
InitBrowser();
}
public void InitBrowser()
{
//初始化参数设置
Cef.Initialize(new CefSettings());
//string pathName = "www.baidu.com";
//打开index.html文件,内嵌显示。
string pathName = Application.StartupPath + "\\" + "index.html";
browser = new ChromiumWebBrowser(pathName);
//设置浏览器字体
Font font = new Font("微软雅黑", 10.5f);
browser.Font = font;
//设置浏览器左上角与winform窗体的相对位置
browser.Left = 0;
browser.Top = 0;
//设置浏览器长宽
browser.Width = 800;
browser.Height = 600;
//浏览器停靠方式
browser.Dock = DockStyle.None;
//browser.Dock = DockStyle.Fill;
//添加浏览器
this.Controls.Add(browser);
//绑定JsEvent类为C#与HTML交互的类,交互的名字为myJStest
CefSharpSettings.LegacyJavascriptBindingEnabled = true;
CefSharpSettings.WcfEnabled = true;
browser.JavascriptObjectRepository.Register("myJStest", new JsEvent(), isAsync: true, options: BindingOptions.DefaultBinder);
var isBound = browser.JavascriptObjectRepository.IsBound("myJStest");
//在浏览器中注册myJStest交互类
browser.ExecuteScriptAsyncWhenPageLoaded(@"(async function() {await CefSharp.BindObjectAsync('myJStest', 'myJStest');})();");
}
public static byte[] Bitmap2Byte(Bitmap bitmap)
{
using (Stream stream1 = new MemoryStream())
{
bitmap.Save(stream1, ImageFormat.Jpeg);
byte[] arr = new byte[stream1.Length];
stream1.Position = 0;
stream1.Read(arr, 0, (int)stream1.Length);
stream1.Close();
return arr;
}
}
private async void button1_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "(*.jpg,*.png,*.jpeg,*.bmp,*.gif)|*.jgp;*.png;*.jpeg;*.bmp;*.gif|All files(*.*)|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
// 调用JavaScript的showImage方法,并传入参数
string fullpath = openFileDialog1.FileName;
string JSfunction = "showImage('";
Mat srcImg = CvInvoke.Imread(fullpath); //读取图片
Image<Bgr, Byte> image = srcImg.ToImage<Bgr, byte>();
Bitmap bImg = image.ToBitmap();
var sendImage = Convert.ToBase64String(Bitmap2Byte(bImg));
JSfunction = JSfunction + "data:image/bmp;base64," + sendImage + "')";
await browser.GetBrowser().MainFrame.EvaluateScriptAsync(JSfunction);//运行页面上js的showImage方法
}
else
{
MessageBox.Show("打开图片失败!!!");
}
}
}
public class JsEvent
{
public void showTest()
{
MessageBox.Show("我是C#中的函数!");
}
public void showTestArg(string ss)
{
MessageBox.Show("我是在C#中收到HTML的返回信号:" + ss);
}
}
}
6、编写一个最简单的index.html
<!DOCTYPE html>
<html>
<head>
<title>这是个标题</title>
</head>
<body>
<h1>这是一个最简单的HTML</h1>
<p>Hello World!</p>
<script>
function showImage(Imagesrc)
{
var receivedImg=new Image();
receivedImg.src=Imagesrc;
document.body.appendChild(receivedImg);
if (typeof myJStest == "undefined") {
alert("myJStest参数未初始化")
return;
}
myJStest.showTestArg('恭喜恭喜,你的图片在JS中显示成功了!');
}
</script>
</body>
</html>
7、将index.html放到执行程序exe所在的bin路径下,然后运行
8、点击“显示图像”
9、显示成功,且信号返回