js加载pdf截屏生成图片调用ocr识别成文字
生成pdf代码:
//pdf //定义上传文件的属性 var param = { fileName: "",//文件名称,上传接口返回 fileSize: "",//文件大小 filePage: "",//文件页数 printnum: "1",//章的编号 多选拼接 例:1,2 pointx: "",//X轴坐标 多选拼接 例:1268,1368 pointy: "",//Y轴坐标 多选拼接 例:590,490 isRidingSeam: 'N', printNums: '1' }; //显示pdf $("#pdf").change(function () { $('#pdfDiv').show(); //关闭左侧pdf弹窗 $('.closePDF').click(function () { $('#pdfDiv').hide(); }); var pdfFileURL = $("#pdf").val(); if (pdfFileURL) { var formData = new FormData(); var file = document.getElementById("pdf").files[0]; formData.append("Files", file); $("#imgDiv").empty();//清空上一PDF文件展示图 var files = $("#pdf").prop('files');//获取到文件 var fileSize = files[0].size; var mb; if (fileSize) { mb = fileSize / 1048576; if (mb > 10) { $.WeMsg("文件大小不能>10M", "ERROR"); return; } } $("#pdfName").text(files[0].name).attr("title", files[0].name); //名称 if (mb !== "") { mb = parseInt(mb); $("#sizeText").text(mb.toFixed(2) + "Mb"); //大小 } //给后端文件附具体的值 param.fileName = files[0].name; param.fileSize = fileSize; /*pdf.js无法直接打开本地文件,所以利用FileReader转换*/ var reader = new FileReader(); reader.readAsArrayBuffer(files[0]); reader.onload = function (e) { var myData = new Uint8Array(e.target.result); var docInitParams = { data: myData }; var typedarray = new Uint8Array(this.result); PDFJS.getDocument(typedarray).then(function (pdf) {//PDF转换为canvas $("#imgDiv").css("border", "0"); //清除文本、边框 if (pdf) { var pageNum = pdf.numPages; if (pageNum >= 2) $('.isRiding').show(); else $('.isRiding').hide(); param.filePage = pageNum; $("#pagesText").text(pageNum); for (var i = 1; i <= pageNum; i++) { var canvas = document.createElement('canvas'); canvas.style.width = '1000px'; canvas.style.borderRadius = '10px'; canvas.style.border = '1px solid #CA7C4E'; canvas.style.margin = '10px'; canvas.id = "pageNum" + i; $("#imgDiv").append(canvas); var context = canvas.getContext('2d'); openPage(pdf, i, context); } } }); $("#imgDiv").show(); }; } });
在$(function(){})中截图代码:
//截图代码 var clientWidth = document.documentElement.clientWidth || document.body.clientWidth; var clientHeight = document.documentElement.clientHeight || document.body.clientHeight; // 更新canvas宽高 $("#bg_canvas").attr("width", clientWidth * 0.4); $("#bg_canvas").attr("height", clientHeight); $("#bg_canvas").hide();
screenshotClick("frmAdd", "imgDiv");
screenshotClick("frm", "dlgimgDiv");
给小按钮赋值:
function screenshotClick(node, obj) { //去掉默认的contextmenu事件,否则会和右键事件同时出现。 $(`#${node} input`).bind("contextmenu", function (e) { if ($(this).attr("type") === "text" || $(this).attr("type") === "number") { return false; } }); $(`#${node} input`).off("mousedown").on("mousedown", function (e) { if (e.button === 2) { if ($(`#${obj}`).children().length !== 0) { if ($(this).attr("type") === "text" || $(this).attr("type") === "number") { $("#itemMenu").show(); $("#itemMenu").css("left", e.pageX + 10 + "px"); $("#itemMenu").css("top", e.pageY + 10 + "px"); $.node = this; } } } }); $(`#${node} textarea`).bind("contextmenu", function (e) { return false; }); $(`#${node} textarea`).off("mousedown").on("mousedown", function (e) { if (e.button === 2) { if ($(`#${obj}`).children().length !== 0) { $("#itemMenu").show(); $("#itemMenu").css("left", e.pageX + 10 + "px"); $("#itemMenu").css("top", e.pageY + 10 + "px"); $.node = this; } } }); $("body").off("click").on("click", function () { $("#itemMenu").hide(); }); } function screenshot() { $("#itemMenu").hide(); $("#bg_canvas").show(); //调用选取截屏 clipScreenshots("bg_canvas"); }
调用截屏:
function screenshot() { $("#itemMenu").hide(); $("#bg_canvas").show(); //调用选取截屏 clipScreenshots("bg_canvas"); }
显示的时候加载pdf:
function evalFile(obj) { var rowData = $(`#${$(obj).parents('table').attr("id")}`).DataTable().row($(obj).parents('tr')[0]).data(); //去后台获取pdf的文件路径,根据文件名,类型,文件编号 var rawLength = ""; $("#dlgimgDiv").empty(); $.ajax({ type: "post", url: "/Engineering/GetFilePathByFile", data: { "fileName": rowData.Wegkoix, 'fileType': rowData.WegkoiZfxn }, success: function (data) { //显示pdf var pdfData = data; pdfData = location.origin + "/" + pdfData.slice(1); PDFJS.getDocument(pdfData).then(function (pdf) {//PDF转换为canvas $("#dlgimgDiv").css("border", "0"); //清除文本、边框 if (pdf) { var pageNum = pdf.numPages; if (pageNum >= 2) $('.isRiding').show(); else $('.isRiding').hide(); $("#pagesText").text(pageNum); for (var i = 1; i <= pageNum; i++) { var canvas = document.createElement('canvas'); canvas.style.width = '1000px'; canvas.style.borderRadius = '10px'; canvas.style.border = '1px solid #CA7C4E'; canvas.style.margin = '10px'; canvas.id = "pageNum" + i; $("#dlgimgDiv").append(canvas); var context = canvas.getContext('2d'); openPage(pdf, i, context); } } }); } }); }
加载 一页的pdf
function openPage(pdfFile, pageNumber, context) { var scale = 2; pdfFile.getPage(pageNumber).then(function (page) { viewport = page.getViewport(scale); var canvas = context.canvas; canvas.width = viewport.width; canvas.height = viewport.height; canvas.style.width = "100%"; canvas.style.height = "100%"; var renderContext = { canvasContext: context, viewport: viewport }; page.render(renderContext); }); return; }
截屏的代码:
//默认画笔线宽 var defaultStrokeWidth = 1;//画矩形选取框的线宽 //选取划线的canvasExt var canvasExt = { //画矩形 画笔颜色 线宽 drawRect: function (canvasId, penColor, strokeWidth) { var that = this; that.penColor = penColor; that.penWidth = strokeWidth; var canvas = document.getElementById(canvasId); //canvas 的矩形框 var canvasRect = canvas.getBoundingClientRect(); //canvas 矩形框的左上角坐标 var canvasLeft = canvasRect.left; var canvasTop = canvasRect.top; // 要画的矩形的起点 xy var x = 0; var y = 0; //鼠标点击按下事件,画图准备 canvas.onmousedown = function (e) { //设置画笔颜色和宽度 var color = that.penColor; var penWidth = that.penWidth; // 确定起点 x = e.clientX - canvasLeft; y = e.clientY - canvasTop; // 添加layer $("#" + canvasId).addLayer({ type: 'rectangle', strokeStyle: color, strokeWidth: penWidth, name: 'areaLayer', fromCenter: false, x: x, y: y, width: 1, height: 1 }); // 绘制 $("#" + canvasId).drawLayers(); $("#" + canvasId).saveCanvas(); //鼠标移动事件,画图 canvas.onmousemove = function (e) { // 要画的矩形的宽高 var width = e.clientX - canvasLeft - x; var height = e.clientY - canvasTop - y; // 清除之前画的 $("#" + canvasId).removeLayer('areaLayer'); $("#" + canvasId).addLayer({ type: 'rectangle', strokeStyle: color, strokeWidth: penWidth, name: 'areaLayer', fromCenter: false, x: x, y: y, width: width, height: height }); $("#" + canvasId).drawLayers(); }; }; //鼠标抬起 canvas.onmouseup = function (e) { var color = that.penColor; var penWidth = that.penWidth; canvas.onmousemove = null; var width = e.clientX - canvasLeft - x; var height = e.clientY - canvasTop - y; $("#" + canvasId).removeLayer('areaLayer'); $("#" + canvasId).addLayer({ type: 'rectangle', strokeStyle: color, strokeWidth: penWidth, name: 'areaLayer', fromCenter: false, x: x, y: y, width: width, height: height }); $("#" + canvasId).drawLayers(); $("#" + canvasId).saveCanvas(); // 把body转成canvas html2canvas(document.body, { scale: 1, // allowTaint: true, useCORS: true //跨域使用 }).then(canvas => { var capture_x, capture_y; if (width > 0) { //从左往右画 capture_x = x + that.penWidth; } else { //从右往左画 capture_x = x + width + that.penWidth; } if (height > 0) { //从上往下画 capture_y = y + that.penWidth; } else { //从下往上画 capture_y = y + height + that.penWidth; } printClip(canvas, capture_x, capture_y, Math.abs(width), Math.abs(height)); }); // 移除画的选取框 $("#" + canvasId).removeLayer('areaLayer'); // 隐藏用于华画取框的canvas $("#" + canvasId).hide(); }; } }; //老石 :选取截屏 function clipScreenshots(canvasId) { canvasExt.drawRect(canvasId, "red", defaultStrokeWidth); } //打印截取区域 截取 截取的起点x 截取的起点y 截取的起点宽 截取的起点高 function printClip(canvas, capture_x, capture_y, capture_width, capture_height) { // 创建一个用于截取的canvas var clipCanvas = document.createElement('canvas'); clipCanvas.width = capture_width; clipCanvas.height = capture_height; // 截取 clipCanvas.getContext('2d').drawImage(canvas, capture_x, capture_y, capture_width, capture_height, 0, 0, capture_width, capture_height) var clipImgBase64 = clipCanvas.toDataURL(); // 生成图片 var clipImg = new Image(); clipImg.src = clipImgBase64; //var con = confirm('识别图片文字吗?取消则保存截图'); //if (con) { //调用后台ocr $.post("/Engineering/CallOcrReturnStr", { urlImage: clipImg.src }, function (res) { if (res !== "") { //把结果添加到文本框 var data = JSON.parse(res); var val = ""; if ($.node.tagName === "INPUT") { data.forEach(item => { val += item.words; }); } else { val=data.map(item=> { return item.words; }).join("\n") } $($.node).val(val); } else { $.WeMsgBox("ocr转换失败"); } }); //调用打印功能 //$(clipImg).print(); //} else { // downloadIamge(clipImgBase64); //} } //下载保存图片 function downloadIamge(imgUrl) { // 图片保存有很多方式,这里使用了一种投机的简单方法。 // 生成一个a元素 var a = document.createElement('a'); // 创建一个单击事件 var event = new MouseEvent('click'); // 生成文件名称 var timestamp = new Date().getTime(); var name = imgUrl.substring(22, 30) + timestamp + '.png'; a.download = name; // 将生成的URL设置为a.href属性 a.href = imgUrl; // 触发a的单击事件 开始下载 a.dispatchEvent(event); }
后端代码:
[HttpPost] public string CallOcrReturnStr(string urlImage) { if (string.IsNullOrEmpty(urlImage)) return ""; //这个地方需要考虑队列 string fileName = ""; if (urlImage.StartsWith("data:image")) fileName = mWeApi.Base64StringToImage(urlImage); else if (urlImage.StartsWith("http:") || urlImage.StartsWith("https:")) //要把图片保存到本地 { } string json = mWeApi.OcrImgConvertToText(fileName); return json; }
[HttpPost] public string GetFilePathByFile(string fileName, string fileType) { if (string.IsNullOrEmpty(fileName) || string.IsNullOrEmpty(fileType)) return ""; string path = "~/Files/TechDoc/" + fileType + "/" + fileName.TrimEnd(); if (System.IO.File.Exists(Server.MapPath(path))) return path; return "文件名不存在"; }
public string SaveFileDoc() { if (Request.Files.Count == 0) return "上传失败,请选择文件"; List<string> listFile = new List<string>(); string path = "~/Files/TechDoc/"; if (!Directory.Exists(Server.MapPath(path))) Directory.CreateDirectory(Server.MapPath(path)); try { for (int i = 0; i < Request.Files.Count; i++) { var file = Request.Files[i]; string fileName = Request.Files[i].FileName; if (string.IsNullOrEmpty(fileName)) return "文件名为空"; fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1); file.SaveAs(Server.MapPath(path + fileName)); } if (path.StartsWith("~")) path = path.Substring(1, path.Length - 1); return "OK" + path; } catch (Exception ex) { return "上传失败"; } }
//base64转图片 public string Base64StringToImage(string base64) { if (string.IsNullOrEmpty(base64)) return ""; //base64 = RemoveByRegex(base64, ".*base64,"); //速度慢 base64 = base64.Replace("data:image/png;base64,", ""); string fileName = ""; try { byte[] bytes = Convert.FromBase64String(base64); if (bytes == null) return null; MemoryStream ms = new MemoryStream(bytes); Bitmap bitmap = new Bitmap(ms); //保存图片,获取url地址 Random rd = new Random(); fileName = DateTime.Now.ToString("yyyyMMddhhmmssfff") + rd.Next(10000, 99999) + ".png"; string path = "~/OcrFile/"; if (!Directory.Exists(System.Web.HttpContext.Current.Server.MapPath(path))) Directory.CreateDirectory(System.Web.HttpContext.Current.Server.MapPath(path)); string imgUrl = path + fileName; if (File.Exists(imgUrl)) File.Delete(imgUrl); else bitmap.Save(System.Web.HttpContext.Current.Server.MapPath(imgUrl), ImageFormat.Png); ms.Close();//关闭当前流,并释放所有与之关联的资源 bitmap.Dispose(); } catch (Exception ex) { LogWriter.Write(LOG_CATEGORY.WIN_UI, LOG_LEVEL.ERROR, "Base64StringToImage:" + ex.ToString()); return null; } return fileName; }
private static object obj = new object(); public string OcrImgConvertToText(string fileName) { if (string.IsNullOrEmpty(fileName)) return ""; var client = new Baidu.Aip.Ocr.Ocr(OCR_API_KEY, OCR_API_SECRET_KEY); client.Timeout = 60000; string imgUrl = System.Web.HttpContext.Current.Server.MapPath("~/OcrFile/" + fileName); if (!File.Exists(imgUrl)) return ""; try { lock (obj) //确保只处理一张图片 { byte[] image = File.ReadAllBytes(imgUrl); JObject result = client.GeneralBasic(image); //过滤掉无用字符 JObject jo = (JObject)JsonConvert.DeserializeObject(result.ToString()); string text = jo["words_result"].ToString(); return text; } } catch (Exception ex) { LogWriter.Write(LOG_CATEGORY.WIN_UI, LOG_LEVEL.ERROR, "OcrImgConvertToText:" + ex.ToString()); return null; } }
html代码:
<div id="itemMenu" style="display:none;position:fixed;z-index: 10000;"> <table border="1" cellspacing="0"> <tr> <td style="cursor:default;padding:5px 10px;border:1px solid #ccc;background:#fff;" align="center" onclick="screenshot()">智能识别</td> </tr> </table> </div>
<div id="pdfs"> <div id="pdfDiv"> <div id="imgDiv" style="margin: 0 auto;width: 595px;min-height: 842px;border: 1px solid #CA7C4E;border-radius: 10px;text-align: center;"> </div> </div> </div>
<a href="javascript:;" class="btn file"> 选择PDF <input id='pdf' data-field="Wegkoix" type='file' name='file' accept="application/pdf"> </a>
引入的js:
@*显示pdf需要的js*@ <script src="~/Content/pdfHelper/js/pdf.js"></script> <script src="~/Content/pdfHelper/js/FileSaver.js"></script> <script src="http://d3js.org/d3.v3.min.js"></script> @*截屏用到的js*@ <script src="~/Content/CommJs/html2canvas.js"></script> <script src="~/Content/CommJs/jQuery.print.js"></script> <script src="~/Content/CommJs/jcanvas.min.js"></script>
效果: