使用vue扫描扫描仪图像

前言

     目前web开发技术经过多年发展之后,大浪淘沙,古老的activex、NPAPI等技术都已经被淘汰,甚至连IE浏览器都已经被淘汰了,国内做web前端开发有大量使用vue技术的公司,在日常业务开发里面如果涉及到驱动扫描仪进行图像扫描都找不到太好的解决方案。

    受浏览器的安全限定,想要通过前端js或typescript直接去操作客户端的硬件设备,如扫描仪、摄像头、身份证读卡器等都不允许,只能通过开启一个本地websocket中转服务去操作硬件外设,本文介绍的是如何使用scanonweb h5版本实现vue图像扫描。

一、前端开发库sdk获取

     点击 https://www.brainysoft.cn/download/clientjs.zip 下载vue 前端sdk库,下载后用开发工具如vscode 打开示例html可以测试了,如下面这样:

   

 

 二、如何使用

     整个前端项目主要依赖一个js文件,即scanonweb.js文件,该文件负责与扫描托盘服务程序进行交互,交互界面可以使用示例程序自带的,也可以根据需要自己进行设计,最好去调用scanonweb.js的方法就可以实现图像扫描了。

   主要关键实现代码解析,下面是vue扫描组件的源码:

<template>
  <div class="scanonweb_panel">
    <div style="height: 20px;background-color:chocolate;">
      <label style="text-align: center;display: inline-block;width: 100%; font-size: 12px;">扫描参数</label>
    </div>
    <form>
      <div class="block">
        <label for="showUI">是否显示组件界面:</label>
        <select id="showUI">
          <option value="true">显示</option>
          <option value="false" selected>不显示</option>
        </select>
      </div>
      <div class="block">
        <label for="devices">扫描设备:</label>
        <select id="devices"></select>
      </div>
      <div class="block">
        <label for="dpi_x">设备输入分辨率:</label>
        <input type="text" id="dpi_x" v-model="dpi_x" style="width: 25px;" /> X
        <input type="text" id="dpi_y" v-model="dpi_y" style="width: 25px;" />
      </div>
      <div class="block">
        <label for="showDialog">是否显示内置对话框:</label>
        <select id="showDialog">
          <option value="true">显示</option>
          <option value="false" selected>不显示</option>
        </select>
      </div>
      <div class="block">
        <label for="feedEnable">自动进纸模式:</label>
        <select id="feedEnable">
          <option value="true">是</option>
          <option value="false" selected>否</option>
        </select>
      </div>
      <div class="block">
        <label for="autoFeed">自动装填纸张:</label>
        <select id="autoFeed">
          <option value="true">是</option>
          <option value="false" selected>否</option>
        </select>
      </div>
      <div class="block">
        <label>双面模式:</label>
        <select id="dupxMode">
          <option value="true">是</option>
          <option value="false" selected>否</option>
        </select>
      </div>
      <div class="block">
        <label>自动纠偏:</label>
        <select id="autoDeskew">
          <option value="true">是</option>
          <option value="false" selected>否</option>
        </select>
      </div>
      <div class="block">
        <label>自动边框检测:</label>
        <select id="autoBorderDetection">
          <option value="true">是</option>
          <option value="false" selected>否</option>
        </select>
      </div>
    </form>
  </div>
</template>
<script>
module.exports = {
  data:function() {
    return {
    showUI: 'false',
    devices: '',
    dpi_x: 300,
    dpi_y: 300,
    }
  },
  props:{
  },
  created: function () {
    //加载scanonweb.js
    this.scanonweb = new ScanOnWeb();
    //响应返回扫描设备列表的回调函数
    this.scanonweb.onGetDevicesListEvent = function (msg) {
      console.log(msg);
      var deviceListDom = document.getElementById('devices');

      //clear devices list
      deviceListDom.innerHTML = "";
      for (var i = 0; i < deviceListDom.childNodes.length; i++) {
        ardeviceListDomea.removeChild(deviceListDom.options[0]);
        deviceListDom.remove(0);
        deviceListDom.options[0] = null;
      }

      //add devices info
      for (var i = 0; i < msg.devices.length; ++i) {
        var opt = document.createElement("option");
        opt.innerHTML = msg.devices[i];
        if (i == msg.currentIndex) {
          opt.selected = true;
        }
        deviceListDom.appendChild(opt);
      }
    }

    // //响应扫描完成事件
    this.scanonweb.onScanFinishedEvent = function (msg) {
      document.getElementById('pdf_viewer').contentWindow.location.reload();
    }
  },
  mounted: function () {
  },
  methods: {
    //开始扫描
    startScan: function () {
      if (document.getElementById("devices").selectedIndex == -1) {
        alert('请先刷新或者选中要使用的扫描设备后再开始扫描!');
        return;
      }

      //以下获取界面中的扫描参数设定
      this.scanonweb.scaner_work_config.dpi_x = dpi_x.value;
      this.scanonweb.scaner_work_config.dpi_y = dpi_y.value;
      this.scanonweb.scaner_work_config.deviceIndex = document.getElementById("devices").selectedIndex;
      this.scanonweb.scaner_work_config.showDialog = document.getElementById("showDialog").value;
      this.scanonweb.scaner_work_config.autoFeedEnable = document.getElementById("feedEnable").value;
      this.scanonweb.scaner_work_config.autoFeed = document.getElementById("autoFeed").value;
      this.scanonweb.scaner_work_config.dupxMode = document.getElementById("dupxMode").value;
      this.scanonweb.scaner_work_config.autoDeskew = document.getElementById("autoDeskew").value;
      this.scanonweb.scaner_work_config.autoBorderDetection = document.getElementById("autoBorderDetection").value;

      //开始发送扫描指令
      this.scanonweb.startScan();
    }
  }
}
</script>
<style>
.scanonweb_panel {
  width: 100%;
  height: 100%;
  background-color: #fff;
}
</style>

在created事件中初始化scanowneb对象,与扫描托盘服务程序进行连接,读取客户端操作系统已安装的扫描设备列表信息进行显示。

 created: function () {
    //加载scanonweb.js
    this.scanonweb = new ScanOnWeb();
    //响应返回扫描设备列表的回调函数
    this.scanonweb.onGetDevicesListEvent = function (msg) {
      console.log(msg);
      var deviceListDom = document.getElementById('devices');

      //clear devices list
      deviceListDom.innerHTML = "";
      for (var i = 0; i < deviceListDom.childNodes.length; i++) {
        ardeviceListDomea.removeChild(deviceListDom.options[0]);
        deviceListDom.remove(0);
        deviceListDom.options[0] = null;
      }

      //add devices info
      for (var i = 0; i < msg.devices.length; ++i) {
        var opt = document.createElement("option");
        opt.innerHTML = msg.devices[i];
        if (i == msg.currentIndex) {
          opt.selected = true;
        }
        deviceListDom.appendChild(opt);
      }
    }

 用户在界面选中要使用哪一个扫描设备,确定好扫描分辨率等参数以后,点击扫描按钮触发以下代码执行:

 methods: {
    //开始扫描
    startScan: function () {
      if (document.getElementById("devices").selectedIndex == -1) {
        alert('请先刷新或者选中要使用的扫描设备后再开始扫描!');
        return;
      }

      //以下获取界面中的扫描参数设定
      this.scanonweb.scaner_work_config.dpi_x = dpi_x.value;
      this.scanonweb.scaner_work_config.dpi_y = dpi_y.value;
      this.scanonweb.scaner_work_config.deviceIndex = document.getElementById("devices").selectedIndex;
      this.scanonweb.scaner_work_config.showDialog = document.getElementById("showDialog").value;
      this.scanonweb.scaner_work_config.autoFeedEnable = document.getElementById("feedEnable").value;
      this.scanonweb.scaner_work_config.autoFeed = document.getElementById("autoFeed").value;
      this.scanonweb.scaner_work_config.dupxMode = document.getElementById("dupxMode").value;
      this.scanonweb.scaner_work_config.autoDeskew = document.getElementById("autoDeskew").value;
      this.scanonweb.scaner_work_config.autoBorderDetection = document.getElementById("autoBorderDetection").value;

      //开始发送扫描指令
      this.scanonweb.startScan();
    }
  }

 扫描程序驱动硬件工作完成以后,会给浏览器发送websocket消息,通过以下回调函数接收扫描结果:

// //响应扫描完成事件
    this.scanonweb.onScanFinishedEvent = function (msg) {
      document.getElementById('pdf_viewer').contentWindow.location.reload();
    }

  上面的示例是将扫描结果以pdf格式进行了展示,如果需要自己处理扫描结果展示,如向canvas直接绘制的话可以这么处理:

  

		//响应扫描完成事件
		scanonweb.onScanFinishedEvent = function (msg) {
			console.log("扫描前:" + msg.imageBeforeCount + " 扫描后:" + msg.imageAfterCount);
			//以下代码用于将新增的扫描图像从扫描服务程序中取回
			for (var i = msg.imageBeforeCount; i < msg.imageAfterCount; i++) {
				scanonweb.getImageById(i);
			}
		}

        //响应获取某一页图像的回调函数
		scanonweb.onGetImageByIdEvent = function (msg) {
			var imageListDom = document.getElementById('imageList');
			var imageDom = document.createElement("img");
			imageDom.width = 300;
			imageDom.height = 300;
			imageDom.src = "data:image/jpg;base64," + msg.imageBase64;
			imageListDom.appendChild(imageDom);
		}

 有时对扫描结果需要进行裁剪编辑处理,可以通过双击扫描托盘服务程序打开扫描结果编辑界面,里面有旋转、裁剪、魔术棒、色彩填充、去黑边等各种图像编辑处理功能,界面如下:

  

 图像都处理好以后,可以通过以下代码上传扫描结果到服务器端保存:

		//按照jpg格式上传所有图像
		function uploadAllImageAsJpgFormat() {
			var uploadUrl = 'http://localhost:8080/uploadjpg';
			for (imageIndex=0;imageIndex<scanonweb.imageCount;imageIndex++){
				scanonweb.uploadJpgImageByIndex(uploadUrl,'1234','test',imageIndex);
			}			
		}

		//按照pdf格式上传所有图像
		function uploadAllImageAsPdfFormat(){
			scanonweb.uploadAllImageAsPdfToUrl('http://localhost:8080/upload','1234','test');	
		}

		//按照tiff格式上传所有图像
		function uploadAllImageAsTiffFormat(){
			scanonweb.uploadAllImageAsTiffToUrl('http://localhost:8080/upload','1234','test');	
		}

  可以将多页扫描结果按多个单页jpg图像格式进行上传,也可以将多页扫描结果直接按单个pdf格式或者tiff图像格式进行上传,后台代码就是普通的接收文件上传的代码,上传图像的时候可以传递一些额外的参数,如图像关联的业务主键id信息等,后台在保存图像数据的同时可以关联业务数据记录。

VueScan可以利用以下设备的高级硬件能力:尼康 LS-30/LS-2000,美能达 Dimage ScanDual,惠普PhotoSmart,尼康 LS-20/LS-1000,宝丽来 SprintScan 35/LE/ES/+,和佳能 CanoScan2700F底片扫描仪。利用 VueScan,你能够比平板扫描仪扫描照片更多地控制最终的图像VueScan 的特性包括:支持 200 种以上的底片类型,在剪取图像时制成关联单,复杂的白色平衡算法,用于检查物体表面暇疵的红外线底片扫描,成批扫描,自动剪取图像,等等。 VueScan是著名的第三方底片扫描仪驱动程序,支持市场可见绝大多数型号的底片扫描仪,可以更为灵活地控制扫描过程,更深入地发掘硬件潜力,获取色彩 完美的高质量扫描结果。VueScan支持200种以上的底片类型,在剪取图像时制成关联单,复杂的白色平衡算法,用于检查物体表面暇疵的红外线底片扫 描,成批扫描,自动剪取图像等等。 随着软件的走红,Vuescan不断升级,功能不断完善,应用界面也越来越美观实用,最后,很多扫描仪厂商干脆将它作为自己扫描仪的配套驱动程序。 随着数码相机的流行,RAW成为很多喜欢的文件格式,Vuescan也与时俱进,增加了RAW文件转换功能,凭借其优秀的图像算法,在RAW文件转换方 面,vuescan也独树一帜。如今,Vuescan已经发展成为一款多功能的图像处理软件,支持多达750款各类扫描仪和200多款能记录RAW文件的 数码相机,并支持Adobe的DNG数字底片格式! 功能: 支持1200种扫描仪 运行在Mac OS X,Windows和Linux 提高您的工作效率和质量的扫描 创建原始扫描文件 ICC配置文件和色彩空间 IT8色彩校正 注册信息: E-mail Address:[email protected] Serial Number:108824250 Customer Number:1560318833 或者(OR) E-mail Address:[email protected] Serial Number:115973638 Customer Number:1608838852
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

peihexian

你的鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值