new Vue({ el: "#container", data: { canvas: null, image: null,//左侧选中的图像 scale: 1, angle: 0, totalAngle: 0, rectificationDialog: false, repSliderValue: 0, selectImageObj: { // "image": image, // "index": index, //"thumbnail":thumbnail index: -1 }, redoStack: [], undoStack: [], startP: null, assistLine: null, assistText: null,//水印辅助提示对象 markText: null,//水印文本对象 selectManyImages: [], urls: [/*{ path: 'fake://fake.jpg', base64: '', thumbnail:thumbnail }*/], licence: 'gE/rN4vZATMg49y/OCFlZA==',//licence serverIP: '127.0.0.1', serverPort: '38999', debugMode: false,//是否是调试模式 fullscreenLoading: false, jsonCommadnHolder: "请输入待发送json命令\n例如{\"func\":\"start_scan\",\"iden\":\"licence\"}", picLocalPath: '', socketCommand: '',//当前输入的socket命令 socketMsg: '',//收到的socket信息 connectEnable: false,//是否可以点击‘连接’按钮 originJson: '',//输入的待格式化json formatedJson: '',//格式化后的json showBigImageDialog: false,//是否显示大图 selectBigImage: '',//当前选中的大图base64 scanMode: 'normal',//当前扫描模式 normal:正常往后添加 insert:在指定位置前后插入 cover:从指定位置开始往后覆盖或者添加 curInsertIndex: -1,//顺序扫描 当前需要插入的位置 curCoverIndex: -1,//覆盖扫描 当前需要覆盖扫描的位置 needCoverCount: -1,//当前需要覆盖扫描的数量 isSetup: false,//是否显示参数设置框 activeName: '1',//设置框的tab位 devices: [],//获取到的设备列表 currDevice: '',//当前选中的设备 deviceOpened: false,//是否已经打开了设备 deviceInited: false,//是否已经初始化了设备 batchIdList: [],//批次列表 showBatchList: true,//是否显示批次列表选择界面 showExportType: true,//是否显示导出文件列表选择界面 currentBatch: '',//当前是哪个批次 isScanning: false,//是否正在扫描中 bindFolderPath: '',//绑定的文件夹 showWaterMark: false,//是否显示水印配置项 showWaterMarkPosition: false,//是否显示水印xy位置 showBatchMarkConfigure: false,//是否显示批量添加水印框 scanParams: {//扫描参数 color_mode: 'color',//"color","gray","binary","auto" page_mode: 'duplex',//"simplex","duplex","filter_blank_general","filter_blank_invoice","fold_in_half" resolution: 200,//dpi 100,150,200,240,300 brightness: 100,//亮度 1~255 contrast: 4,//对比度 1~7 gamma: 1.00,//伽马值 0.01~5.00 paper_size: 'a4',//纸张尺寸 "a3","a4","a4_horz","auto" paper_cut_enabled: false,//是否裁剪 paper_cut_left: 0.0,//单位毫米 paper_cut_top: 0.0,// paper_cut_right: 210.0,// paper_cut_bottom: 297.0,// auto_crop: false//是否纠偏 }, //扫描参数的范围,后面根据实际获取到的覆盖更新 scanParamsRange: { color_mode_list: ["color", "gray", "binary", "auto"], page_mode_list: ["simplex", "duplex", "filter_blank_general", "filter_blank_invoice", "fold_in_half"], resolution_list: [100, 150, 200, 240, 300], brightness_min: 1, brightness_max: 255, contrast_min: 1, contrast_max: 7, gamma_min: 0.01, gamma_max: 5.00, paper_size_list: ["a3", "a4", "a4_horz", "auto"], paper_size_width: 210.0, paper_size_height: 297.0 }, //全局配置 globalConfig: { file_save_path: 'C:\\', // 默认是文档目录 file_name_prefix: 'Doc', // 文件名前缀 file_name_mode: 'date_time', // 可以是date_time、random image_format: 'jpg', // 格式,支持jpg、bmp、png、tif、pdf、ofd、ocr-pdf和ocr-ofd image_jpeg_quality: 80, // jpg质量,0-100 image_tiff_compression: 'lzw', // 可以为none、 lzw和jpeg image_tiff_jpeg_quality: 80, // tiff-jpeg质量,0-100 }, //上传配置 uploadConfig: { remote_file_path: '/images', upload_mode: 'none', http_host: '', http_port: 80, http_path: '/upload.cgi', ftp_user: 'administrator', ftp_password: '2018', ftp_host: '192.168.0.22', ftp_port: 21 }, //水印信息 waterMarkInfo: { text: '0001', text_color: '#000000', text_opacity: 100, // 不透明度 text_pos: 'left', // 可以是left、right、top、bottom、left_top、right_top、left_bottom、right_bottom、center和location margin_left: 10, // 左边距 margin_top: 10, // 上边距 margin_right: 10, // 右边距 margin_bottom: 10, // 下边距 location_x: 100, // x坐标 location_y: 100, // y 坐标 font_name: '宋体', // 字体名 font_size: 20, // 字号 font_bold: false, // 粗体 font_underline: false, // 下划线 font_italic: false, // 斜体 font_strikeout: false, // 删除线 }, waterMarkPositionList: ['底部居中', '顶部居中', '居中', '左侧居中', '右侧居中', '左上角', '左下角', '右上角', '右下角', '绝对位置XY'], waterMarkPositionSignList: ['bottom', 'top', 'center', 'left', 'right', 'left_top', 'left_bottom', 'right_top', 'right_bottom', 'location'], markPosition: 'bottom', markAbsoluteX: 0,//绝对位置X markAbsoluteY: 0,//绝对位置Y markMarginTop: 0, markMarginLeft: 0, markMarginRight: 0, markMarginBottom: 0, markInsertRange: [0, 0], markFontNameList: ['宋体'], markFontSizeList: [], markFontName: '宋体', markFontSize: 20, markFontBold: false, markFontUnderline: false, markFontItalic: false, markFontStrikeout: false, waterMarkText: '', markFontColor: '#000000', markPredefineColors: [ '#000000', '#ffffff', '#ff4500', '#ff8c00', '#ffd700', '#90ee90', '#00ced1', '#1e90ff', '#c71585', ], markPositionTipX: 0,//提示X markPositionTipY: 0,//提示Y insertQueue: [{ insertType: -1,// 插入类型 -1占位啥都没有 1.加到末尾 2.插入到指定位置 3.覆盖指定位置图片 imagePath: '',//插入图像的路径 insertIndex: 0, //插入位置 idenInfo: {},//签名 }],//插入队列,等待结果返回再继续插入 insertLoopWork: Number, }, created: function () { window.eleLoadding = this.eleLoadding; window.eleAlert = this.eleMessage; window.scanCallBack = this.scanCallBack; window.setupWindowCallBack = this.setupWindowCallBack window.socketCallBack = this.onSocketCallBack window.onbeforeunload = this.onCloseScreen var that = this; this.insertQueue.length = 0 this.insertLoopWork = setInterval(() => { //首位不是占位数据的 if (that.insertQueue.length > 0 && that.insertQueue[0].insertType !== -1) { //先取出队列的第一位 var insertInfo = that.insertQueue.splice(0, 1) // console.log('循环任务:' + JSON.stringify(insertInfo)) // var insertInfo = that.insertQueue[0] console.log('loop work:' + insertInfo[0].insertType + ' ' + insertInfo[0].imagePath) //先取出队列的第一位 // that.insertQueue.splice(0, 1) //插入占位数据 that.insertQueue.splice(0, 0, {insertType: -1}) that.insertAction(insertInfo[0]) } }, 400); }, mounted: function () { var canvasContainer = $("#canvas-container") var width = canvasContainer.width(); var height = canvasContainer.height(); console.log('canvas width:' + width + ' height:' + height) var canvas = new fabric.Canvas( 'imageCanvas', { allowTouchScrolling: true, centeredRotation: true, centeredScaling: true, defaultCursor: 'default', hoverCursor: 'default', backgroundColor: "#ffffff", backgroundVpt: true, width: width, height: height } ); this.canvas = canvas; var that = this canvas.on('mouse:out', function (options) { console.log('Mouse out of canvas'); // if (that.markText) { // canvas.remove(that.markText) // } if (that.assistText) { canvas.remove(that.assistText) } if (that.assistLine) { canvas.remove(that.assistLine) } }); this.markFontSizeList.length = 0 //添加可选字体大小 for (var i = 11; i < 51; i++) { this.markFontSizeList.push(i) } this.initWebSocket() }, methods: { initWebSocket: function () { this.WebScanController = new WebScanController({ wsUrl: 'ws://' + this.serverIP + ':' + this.serverPort + '/', wslicence: this.licence }); this.WebScanController.initSocketIo(this.onSocketCallBack) }, onSocketCallBack: function (info) { switch (info.code) { case SOCKET_CONNECTED://连接成功 this.connectEnable = false this.initData() console.log('socket connected') break case SOCKET_DISCONNECTED://断开连接 this.connectEnable = true console.log('socket disconnect !!!') break case SOCKET_EVENT://其他事件 var parsedInfo = JSON.parse(info.data) this.dispatchEvent(parsedInfo) if (parsedInfo.func) { if (parsedInfo.func === 'scan_image') { console.log('socket received scan_image image_path:' + parsedInfo.image_path) } else if (parsedInfo.func === 'insert_local_image') { console.log('socket received insert_local_image') } else if (parsedInfo.func === 'modify_image') { console.log('socket received modify_image') } else { console.log('socket received: ' + info.data) } } break } // this.appendLog(msg) }, dispatchEvent: function (info) { if (info.func) { if (info.func === 'is_device_init' || info.func === 'get_curr_device_name') { //单独处理 ret 0 初始化了 非0 未初始化 var funcName = this.WebScanController.getCallBack(info.func) if (funcName) { funcName(info) } } else { if (info.ret != null && info.ret != undefined) { if (info.ret == 0) {//返回成功 var funcName = this.WebScanController.getCallBack(info.func) if (funcName) { funcName(info) } else { this.commonDispatch(info) } } else {//统一异常处理 弹个窗 this.eleUnloadding() this.eleMessage(info.err_info ? info.err_info : '未知异常', 'error') if (info.func != null && info.func != undefined) { if (info.func === 'image_add_watermark') {//特殊情况单独处理 //添加水印失败了 // this.reLoadImageList() } } } } else { this.commonDispatch(info) } } } }, commonDispatch: function (info) {//较通用事件处理 this.eleUnloadding() // console.log('commonDispatch:', JSON.stringify(info)) if (info) { switch (info.func) { case "device_arrive"://设备装载 this.eleMessage("设备已装载") break case "device_remove"://设备卸载 this.eleMessage("设备已移除!") this.deinitDevices() this.deviceOpened = false this.deviceInited = false this.devices.length = 0 this.currDevice = null break case "scan_begin"://开始扫描信号 this.isScanning = true this.eleMessage("开始扫描") this.eleLoadding() break case "scan_end"://扫描结束 this.isScanning = false this.clearCanvasData() this.eleMessage("扫描结束") clearInterval(window.loopinterval) this.eleUnloadding() break case "scan_info": // { // “is_error”:false,// 是否是错误消息 // “info”:”start scanning” // 消息内容 // } this.eleMessage(info.info, info.is_error ? 'error' : 'warning') break case "scan_image"://图片回调 var imagePath = info.image_path if (this.scanMode == 'insert') {//是插入扫描 this.curCoverIndex = -1 //找到文件位置,插入元素 if (this.curInsertIndex != -1) { } else { this.curInsertIndex = this.selectImageObj.index } console.log('插入扫描:队列插入位:' + this.curInsertIndex + " path:" + imagePath) this.insertQueue.push({ insertType: 2, imagePath: imagePath, insertIndex: this.curInsertIndex, idenInfo: { insertType: 2, insertIndex: this.curInsertIndex, path: imagePath, base64: info.image_base64 },//签名 }) this.curInsertIndex++ } else if (this.scanMode == 'cover') {//是覆盖扫描 console.log('覆盖扫描,起始位index' + this.curCoverIndex + ' imagePath:' + imagePath + ' 总长度位置:' + (this.urls.length - 1)) console.log('需要覆盖的数量:' + this.needCoverCount) this.insertQueue.push({ insertType: 3, imagePath: imagePath, idenInfo: { insertType: 3, path: imagePath, base64: info.image_base64 }, }) } else {//正常按顺序 this.curCoverIndex = -1 console.log('顺序扫描,队列插入位' + this.curInsertIndex + ' imagePath:' + imagePath) this.insertQueue.push({ insertType: 1, imagePath: imagePath, insertIndex: this.curInsertIndex, idenInfo: { insertType: 1, path: imagePath, insertIndex: this.curInsertIndex, base64: info.image_base64 },//签名 }) this.curInsertIndex++ } break } } }, //扫描展示逻辑 insertAction: function (info) { /* { insertType: 1, imagePath: imagePath, insertIndex: this.insertIndex, idenInfo: { insertType: 2, path: imagePath, insertIndex: this.insertIndex, base64: info.image_base64 }*/ var that = this if (info.insertType === 3) {//是覆盖扫描逻辑 if (this.needCoverCount > 0) {//还在覆盖范围内,直接覆盖掉 this.WebScanController.modifyImage(this.curCoverIndex, info.idenInfo.base64, info.idenInfo, function (modifyInfo) { var idenInfo = JSON.parse(modifyInfo.iden); console.log('覆盖前:index==' + that.curCoverIndex + ' path:' + that.urls[that.curCoverIndex].path) that.urls[that.curCoverIndex] = { // base64: idenInfo.base64, thumbnail: idenInfo.base64, path: idenInfo.path } console.log('覆盖后:index==' + that.curCoverIndex + ' path:' + that.urls[that.curCoverIndex].path) that.curCoverIndex++ that.needCoverCount-- that.$forceUpdate() //把占位符删掉 继续下一轮循环 if (that.insertQueue.length > 0 && that.insertQueue[0].insertType === -1) { that.insertQueue.splice(0, 1) } }) } else {//之后都是新增的往后添加了 this.WebScanController.insertLocalImage(info.imagePath, this.urls.length, info.idenInfo, function (result) { console.log('覆盖扫描:插入成功 index:' + that.urls.length) var idenInfo = JSON.parse(result.iden); that.urls.push({ path: idenInfo.path, thumbnail: idenInfo.base64, // base64: idenInfo.base64 }) that.$forceUpdate() that.$nextTick(function () { if (that.$refs.imageArea) { that.$refs.imageArea.scrollTop = that.$refs.imageArea.scrollHeight } }) //把占位符删掉 继续下一轮循环 if (that.insertQueue.length > 0 && that.insertQueue[0].insertType === -1) { that.insertQueue.splice(0, 1) } }) } } else { this.WebScanController.insertLocalImage(info.imagePath, info.insertIndex, info.idenInfo, function (result) { var idenInfo = JSON.parse(result.iden); if (idenInfo.insertType === 1) { //正常扫描,往后添加 console.log('正常扫描:插入成功 index:' + idenInfo.insertIndex + ' path:' + idenInfo.path) //插入到正确位置 that.urls.splice(idenInfo.insertIndex, 0, { path: idenInfo.path, thumbnail: idenInfo.base64, // base64: idenInfo.base64 }) that.$nextTick(function () { if (that.$refs.imageArea) { that.$refs.imageArea.scrollTop = that.$refs.imageArea.scrollHeight } }) } else if (idenInfo.insertType === 2) { //插入扫描,指定位置 console.log('插入扫描:插入index' + idenInfo.insertIndex + ' path:' + idenInfo.path) //插入到正确位置 that.urls.splice(idenInfo.insertIndex, 0, { path: idenInfo.path, thumbnail: idenInfo.base64, // base64: idenInfo.base64 }) that.$forceUpdate() } //把占位符删掉 继续下一轮循环 if (that.insertQueue.length > 0 && that.insertQueue[0].insertType === -1) { that.insertQueue.splice(0, 1) } }) } }, //一些初始化操作 initData: function () { var that = this this.getGlobalConfig() this.getBatchList(function () { that.changeBatch(that.batchIdList.slice(-1)[0]) }) }, //界面销毁 onCloseScreen: function () { this.releaseService() if (this.insertLoopWork) { clearInterval(this.insertLoopWork) } }, //关闭服务 releaseService: function () { console.log('releaseService') this.deinitDevices() // this.stopBindFolder() if (this.WebScanController) { this.WebScanController.disconnect() } }, /*******************************************扫描仪控制***************************************************************/ //获取全局参数 getGlobalConfig: function () { var that = this this.WebScanController.getGlobalConfig(function (info) { console.log('getGlobalConfig :' + info) that.globalConfig = info var pre = info.file_save_path if (pre.endsWith("\\")) { that.bindFolderPath = pre + 'auto' } else { that.bindFolderPath = pre + '\\auto' } that.bindFolder() }) }, //设置全局参数 setGlobalConfig: function () { var that = this this.WebScanController.setGlobalConfig(this.globalConfig, function (info) { that.eleMessage("设置全局配置成功") }) }, //初始化设备 initDevice: function (succcallBack) { var that = this this.WebScanController.isDeviceInit(function (info) { console.log('isDeviceInit:' + JSON.stringify(info)) if (info.ret === 0) { //已经初始化 that.deviceInited = true if (succcallBack != null) { succcallBack() } } else { //没有初始化 console.log('start device init ' + new Date().getTime()) that.WebScanController.initDevice(function (info) { console.log('init devices :' + JSON.stringify(info) + ' ' + new Date().getTime()) that.deviceInited = true if (succcallBack != null) { succcallBack() } }) } }) }, //反初始化设备(需初始化后调用) deinitDevices: function () { if (this.deviceInited == false) { return } var that = this this.WebScanController.deinitDevices(function (info) { console.log('deinit Devices :' + info) that.deviceInited = false that.deviceInited = false }) }, //获取设备列表 getDeviceNameList: function () { var that = this this.WebScanController.getDeviceNameList(function (info) { console.log('getDeviceNameList :' + JSON.stringify(info)) if (info.device_name_list) {//反初始化成功 for (var i = 0; i < info.device_name_list.length; i++) { console.log('getDeviceNameList index:' + i + " item:" + info.device_name_list[i]) } that.devices = info.device_name_list } }) }, //打开设备 openDevice: function (deviceName) { var that = this this.WebScanController.getCurrDeviceName(function (info) { console.log('getCurrDeviceName:' + JSON.stringify(info)) if (info.device_name) { that.deviceOpened = true that.eleLoadding() that.getScanParams() } else { that.WebScanController.openDevice(deviceName, function (info) { console.log('open devices :' + JSON.stringify(info)) that.deviceOpened = true that.eleLoadding() that.getScanParams() }) } }) }, //关闭设备 closeDevice: function () { if (this.deviceOpened == false) { return } var that = this this.WebScanController.closeDevice(function (info) { console.log('close devices :' + info) that.deviceOpened = false }) }, //设置扫描参数 setScanParams: function () { var that = this var ori = this.scanParams var result = new Array() for (var i = 0; i < ori.length; i++) { var group = ori[i].group_param for (var j = 0; j < group.length; j++) { if (group[j].value != undefined) { result.push({ name: group[j].name, value: group[j].value }) } } } this.WebScanController.setScanParams(result, function (info) { that.eleMessage("设置扫描参数成功") }) }, //获取扫描参数 getScanParams: function () { var that = this this.WebScanController.getScanParams(function (info) { that.eleUnloadding() // console.log('获取到的扫描参数 :' + JSON.stringify(info)) that.scanParamsRange = info.device_param that.parameterCoerceIn() }) }, //重设扫描参数 resetScanParams: function () { var that = this this.WebScanController.resetScanParams(function (info) { console.log('重置参数成功!') that.getScanParams() that.$alert('扫描参数已重置!', '提示', { confirmButtonText: '确定' }); }) }, // setScanParams: function () { // var that = this // this.WebScanController.setScanParams(this.scanParams, function (info) { // console.log('setScanParams :' + info) // that.eleMessage("设置扫描参数成功") // }) // }, //获取扫描参数 // getScanParams: function () { // var that = this // this.WebScanController.getScanParams(function (info) { // that.eleUnloadding() // console.log('获取到的扫描参数 :' + JSON.stringify(info)) // that.scanParamsRange = info // that.parameterCoerceIn() // }) // }, //获取当前设备名称 getCurrDeviceName: function () { this.WebScanController.getCurrDeviceName(function (info) { console.log('getCurrDeviceName :' + info) }) }, //绑定文件夹,以使对图片的插入、移动、删除等,文件名能正确按顺序命名 bindFolder: function () { if (this.bindFolderPath == null || this.bindFolderPath.length == 0) { return } console.log('start bind folder :' + this.bindFolderPath) this.WebScanController.bindFolder(this.bindFolderPath, function (info) { console.log('绑定文件夹成功!') }) }, //停止绑定文件夹 stopBindFolder: function () { this.WebScanController.stopBindFolder(function (info) { console.log('解绑文件夹成功!') }) }, //清理全局保存文件 clearGlobalFileSavePath: function () { var that = this this.$confirm('全局扫描文件删除后无法恢复, 是否继续?', '清理全局保存文件', { confirmButtonText: '继续', cancelButtonText: '取消', type: 'warning', callback: function (value) { if (value == "confirm") { that.eleLoadding(); that.WebScanController.clearGlobalFileSavePath(function (info) { that.eleUnloadding() that.eleMessage('清理全局保存文件成功') console.log('清理全局保存文件成功') }) } } }); }, //开始扫描 startScan: function () { if (this.isScanning) { this.eleMessage('请先等待扫描结束!', 'warning') return; } this.scanMode = 'normal' this.curInsertIndex = this.urls.length this.WebScanController.startScan(function (info) { }) }, //插入扫描 insertScan: function () { var that = this if (this.selectImageObj == null || this.selectImageObj.image == null || this.selectImageObj.image.base64 == undefined) { this.eleMessage("请选择插入图像", "warning"); return; } if (this.isScanning) { this.eleMessage('请先等待扫描结束!', 'warning') return; } this.WebScanController.startScan(function (info) { console.log('插入扫描') that.scanMode = 'insert' }) }, //覆盖扫描 coverScan: function () { if (this.selectImageObj == null || this.selectImageObj.image == null || this.selectImageObj.image.base64 == undefined) { this.eleMessage("请选择插入图像", "warning"); return; } if (this.isScanning) { this.eleMessage('请先等待扫描结束!', 'warning') return; } var that = this this.curInsertIndex = -1 this.curCoverIndex = this.selectImageObj.index this.needCoverCount = this.urls.length - this.curCoverIndex this.WebScanController.startScan(function (info) { console.log('覆盖扫描') that.scanMode = 'cover' }) }, //停止扫描 stopScan: function () { this.WebScanController.stopScan(function (info) { console.log('stopScan :' + info) }) }, //保存扫描仪参数 saveParams: function () { this.isSetup = false this.setGlobalConfig() this.setScanParams() this.bindFolder() }, onDeviceChanged: function (deviceName) { this.closeDevice() this.openDevice(deviceName) }, openDeviceSetting: function () { console.log('准备打开设置') if (this.deviceInited == true) { this.isSetup = true } else { var that = this console.log('准备初始化设备...') this.initDevice(function () { console.log('初始化设备结束') that.isSetup = true setTimeout(function () { console.log('准备获取设备列表...') that.getDeviceNameList() }, 500); }) } }, /*******************************************文件管理***************************************************************/ //获取最后批次的内容 getBatchList: function (succeccCallBack) { var that = this this.WebScanController.getBatchIdList(function (info) { console.log('批次列表:' + JSON.stringify(info)) that.batchIdList.length = 0 for (var i = 0; i < info.batch_id_list.length; i++) { that.batchIdList.push(info.batch_id_list[i]) } succeccCallBack() }) }, //删除批次 deleteBatch: function (batchId, index) { if (!this.batchIdList.includes(batchId)) { this.eleMessage('该批次[' + batchId + ']不存在!', 'warning') return } console.log('当前批次号:' + this.currentBatch) console.log('要删除的批次号:' + batchId, '是否是当前批次:' + (this.currentBatch === batchId)) var that = this this.WebScanController.deleteBatch(batchId, function (info) { console.log('删除批次成功 batchId:' + batchId + " result:" + JSON.stringify(info)) that.batchIdList.splice(index, 1) if (that.currentBatch === batchId) {//删除的就是当前批次 var lastBatchId = that.batchIdList.slice(-1)[0] console.log('删除的当前批次,那么重新打开最新的批次:' + lastBatchId) that.changeBatch(lastBatchId) } }) }, //创建新的批次 createNewBatch: function () { var that = this this.$prompt('请输入批次号', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', inputValidator: function (value) { if (value == null || value == undefined || value.length == 0 || new RegExp("^[ ]+$").test(value)) { that.eleMessage('批次号不能为空') return false } else { return true } } }).then(({value}) => { that.eleLoadding() var id = value.trim() console.log('id:' + id) that.WebScanController.createNewBatch(id, function (info) { that.eleUnloadding() console.log('创建新批次 batchId:' + id + " " + JSON.stringify(info)) that.showBatchList = false that.urls.length = 0 that.batchIdList.push(id) that.currentBatch = id }) }).catch(() => { }); }, //切换批次 changeBatch: function (batchId) { var that = this console.log('切换批次:' + batchId) this.showBatchList = false this.image = null this.undoStack.length = 0; this.redoStack.length = 0; this.eleLoadding() this.WebScanController.openBatch(batchId, function (info) { console.log('打开批次:' + JSON.stringify(info)) that.urls.length = 0//先清空一下 that.currentBatch = batchId //重新加载 that.reLoadImageList() }) }, //获取当前批次的图像列表 reLoadImageList: function () { var that = this this.eleLoadding() this.clearCanvasData() /* this.WebScanController.getImageCount(function (info) { that.eleUnloadding() console.log('当前批次图片数量为:' + JSON.stringify(info)) that.urls = new Array(info.image_count).fill('') for (var i = 0; i < that.urls.length; i++) { that.WebScanController.loadImage(i, function (imageInfo) { console.log('iden===' + imageInfo.iden) that.urls[imageInfo.iden] = { path: '', base64: imageInfo.image_base64 } that.$forceUpdate() console.log('加载批次图片 index:' + i + " info:" + JSON.stringify(imageInfo)) console.log('urls结果:' + that.urls) }) } })*/ //获取缩略图 this.WebScanController.getImageThumbnailList(function (info) { that.eleUnloadding() // “image_thumbnail_list”:[{“image_tag”:”001”, “image_base64”:”xxx”}] console.log('缩略图个数:' + info.image_thumbnail_list.length) that.urls.length = 0 for (var i = 0; i < info.image_thumbnail_list.length; i++) { that.urls.push({ path: '', base64: '', thumbnail: info.image_thumbnail_list[i].image_base64//缩略图 }) } that.$forceUpdate() }) }, modifyBatchId: function (originBatchId, index) { var that = this this.$prompt('请输入新的批次号', '更改批次号', { confirmButtonText: '确定', cancelButtonText: '取消', inputValidator: function (value) { if (value == null || value == undefined || value.length == 0 || new RegExp("^[ ]+$").test(value)) { that.eleMessage('批次号不能为空') return false } else { return true } } }).then(({value}) => { that.eleLoadding() var id = value.trim() that.WebScanController.modifyBatchId(originBatchId, id, function (info) { that.eleUnloadding() console.log('修改批次号 newbatchId:' + id + " originBatchId:" + originBatchId + " " + JSON.stringify(info)) that.showBatchList = false that.batchIdList[index] = id if (that.currentBatch == originBatchId) { that.currentBatch = id } that.eleMessage('修改批次号成功!') }) }); }, //清空批次图像 clearBatch: function () { var that = this this.WebScanController.clearImageList(function (info) { that.eleMessage('清空图像列表成功!') console.log('清空图像列表:' + JSON.stringify(info)) that.urls.length = 0 that.image = null that.canvas.clear() that.$forceUpdate() }) }, deleteSelectedImage: function () { if (this.selectImageObj == null || this.selectImageObj.image == null || this.selectImageObj.image.base64 == undefined) { this.eleMessage("请至少选择一张需要删除的图像", "warning"); return; } var deleteList = this.selectManyImages console.log('删除列表:' + deleteList) var that = this this.WebScanController.deleteImage(deleteList, function (info) { that.image = null that.selectManyImages.sort(function (a, b) { return a - b }) for (var i = that.selectManyImages.length - 1; i >= 0; i--) { that.urls.splice(that.selectManyImages[i], 1) } that.selectImageObj = {index: -1} that.selectManyImages = [] that.image = null that.$forceUpdate() }) }, //图片书籍排序 bookSort: function () { if (this.urls == null || this.urls.length <= 0) { this.eleMessage("该批次不包含图像", "warning"); return; } var that = this; this.$confirm('图片书籍排序后不可撤销, 是否继续?', '书籍排序', { confirmButtonText: '继续', cancelButtonText: '取消', type: 'warning', callback: function (value) { if (value == "confirm") { that.eleLoadding(); that.WebScanController.imageBookSort(function (info) { that.eleUnloadding() console.log('书籍排序:' + JSON.stringify(info)) that.reLoadImageList() }) } } }); }, //合并图像 mergeHorizontal: function (isHorizontal) { if (this.selectManyImages == null || this.selectManyImages.length < 2) { this.eleMessage('请至少选择两张图像进行合并') return } var that = this this.WebScanController.mergeImage(this.selectManyImages, isHorizontal ? 'horz' : 'vert', 'center', true, function (mergeInfo) { console.log('合并图像:' + JSON.stringify(mergeInfo)) // that.reLoadImageList() that.WebScanController.deleteImage(that.selectManyImages, function (deleteInfo) { console.log('合并图像:删除原图成功!') that.selectManyImages.sort(function (a, b) { return a - b }) for (var i = that.selectManyImages.length - 1; i >= 0; i--) { that.urls.splice(that.selectManyImages[i], 1) } that.WebScanController.insertImage(mergeInfo.image_base64, that.urls.length, function (insertInfo) { console.log('合并图像:插入图片成功') that.urls.push({ path: mergeInfo.image_path, thumbnail: mergeInfo.image_base64, base64: mergeInfo.image_base64 }) }) }) }) }, //图片互换 exchangeImage: function () { if (this.selectManyImages == null || this.selectManyImages.length != 2) { this.eleMessage('请选择两张图像进行交换!') return } var firstIndex = this.selectManyImages[0] var secondIndex = this.selectManyImages[1] var that = this this.WebScanController.exchangeImage(firstIndex, secondIndex, function (info) { console.log('图片交换成功!' + JSON.stringify(info)) that.clearCanvasData() var firstData = that.urls[firstIndex] var secondData = that.urls[secondIndex] that.urls[firstIndex] = secondData that.urls[secondIndex] = firstData that.$forceUpdate() }) }, //导出全部图片为指定文件类型 exportFile: function (fileType) { if (this.urls.length == 0) { this.eleMessage('请先扫描!', 'warning') return } this.eleLoadding() var imageIndexList = [] for (var i = 0; i < this.urls.length; i++) { imageIndexList.push(i) } console.log('待导出文件index:' + imageIndexList) var that = this if (fileType === 'zip') { this.WebScanController.makeZipFile(imageIndexList, function (info) { console.log('导出zip压缩包成功:' + JSON.stringify(info)) that.eleUnloadding() that.downloadBase64File(info.zip_base64, that.currentBatch + ".zip") }) } else { this.WebScanController.makeMultiImage(imageIndexList, fileType, function (info) { that.eleUnloadding() var fileName = that.currentBatch + "." + fileType console.log('导出文件成功:' + JSON.stringify(info)) that.downloadBase64File(info.image_base64, fileName) }) } }, //添加水印 addWaterMarkWithBatch: function () { var that = this that.canvas.remove(that.assistText) that.$confirm('水印添加后不可撤销, 是否继续?', '添加水印', { confirmButtonText: '继续', cancelButtonText: '取消', type: 'warning' } ).then(() => { that.showBatchMarkConfigure = false that.waterMarkInfo.text = that.waterMarkText that.waterMarkInfo.text_color = that.markFontColor that.waterMarkInfo.text_pos = that.markPosition that.waterMarkInfo.text_opacity = 100 that.waterMarkInfo.margin_left = that.markMarginLeft that.waterMarkInfo.margin_top = that.markMarginTop that.waterMarkInfo.margin_right = that.markMarginRight that.waterMarkInfo.margin_bottom = that.markMarginBottom that.waterMarkInfo.location_x = that.markAbsoluteX that.waterMarkInfo.location_y = that.markAbsoluteY that.waterMarkInfo.font_name = that.markFontName that.waterMarkInfo.font_size = that.markFontSize that.waterMarkInfo.font_bold = that.markFontBold that.waterMarkInfo.font_underline = that.markFontUnderline that.waterMarkInfo.font_italic = that.markFontItalic that.waterMarkInfo.font_strikeout = that.markFontStrikeout console.log(JSON.stringify(that.waterMarkInfo)) console.log('范围:' + that.markInsertRange) if (that.markInsertRange[1] - that.markInsertRange[0] == 0) {//只选择了一页 var modifyIndex = that.markInsertRange[0] - 1 that.WebScanController.imageAddWatermark(modifyIndex, that.waterMarkInfo, true, function (info) { console.log('添加水印成功:') that.WebScanController.modifyImage(modifyIndex, info.image_base64, {}, function (modifyInfo) { console.log('添加水印:修改' + modifyIndex + '成功:') that.urls[modifyIndex].thumbnail = info.image_base64 that.urls[modifyIndex].base64 = info.image_base64 that.selectImage(that.urls[modifyIndex], modifyIndex) that.$forceUpdate() }) }) } else {//选择了多张 var startIndex = that.markInsertRange[0] - 1 that.curModifyIndex = startIndex that.addWaterMarkSingle(startIndex, that.waterMarkInfo, that.addWaterMarkCallback) } }) .catch(() => { }) }, addWaterMarkCallback: function () { this.curModifyIndex++ if (this.curModifyIndex <= this.markInsertRange[1] - 1) { console.log('继续处理水印:' + this.curModifyIndex) this.addWaterMarkSingle(this.curModifyIndex, this.waterMarkInfo, this.addWaterMarkCallback) } else { console.log('水印循环结束:' + this.curModifyIndex) } }, addWaterMarkSingle: function (imageIndex, markInfoParams, succCallBack) { var that = this this.WebScanController.imageAddWatermark(imageIndex, markInfoParams, true, function (markInfo) { console.log('多张添加水印成功:index:' + imageIndex) var resultImage = markInfo.image_base64 that.WebScanController.modifyImage(imageIndex, resultImage, {}, function (modifyInfo) { console.log('多张添加水印:修改' + imageIndex + '成功:') that.urls[imageIndex].thumbnail = resultImage that.urls[imageIndex].base64 = resultImage that.selectImage(that.urls[imageIndex], imageIndex) that.$forceUpdate() succCallBack() }) }) }, //文件上传 uploadFile: function () { var data = this.urls if (data.length == 0) { this.eleMessage('请先扫描!') return } for (var index = 0; index < data.length; index++) { var path = data[index].path var config = this.uploadConfig var fileName = path.slice(path.lastIndexOf('\\') + 1, path.length) if (fileName.length == 0) { fileName = this.currentBatch + '-' + index + ".jpg" } console.log('fileName:' + fileName) var remoteFilePath = config.remote_file_path if (!remoteFilePath.startsWith("/")) { remoteFilePath = "/" + remoteFilePath } remoteFilePath = remoteFilePath.endsWith("/") ? remoteFilePath + fileName : remoteFilePath + "/" + fileName console.log('全路径名:' + remoteFilePath) this.WebScanController.uploadImage(index, config.upload_mode, remoteFilePath, config.http_host, config.http_port, config.http_path, config.ftp_user, config.ftp_password, config.ftp_host, config.ftp_port, function (info) { console.log('上传完成:' + JSON.stringify(info)) }) } }, /*******************************************canvas图像处理***************************************************************/ selectImage: function (image, index) { var that = this if (image.base64 == null || image.base64 == undefined || image.base64.length == 0) { that.eleLoadding() // { // path: '', // base64: '', // thumbnail: base64//缩略图 // } that.WebScanController.loadImage(index, function (oriImageInfo) { console.log('加载原图成功 index:' + index) that.eleUnloadding() that.urls[index].base64 = oriImageInfo.image_base64 that.selectImage(that.urls[index], index) }) } else { that.selectImageObj = { "image": image, "index": index } console.log("selectImage: " + that.selectImageObj.index) that.loadImageToCanvas(image); that.selectManyImages = new Array(); that.selectManyImages.push(index); that.undoStack.length = 0; that.redoStack.length = 0; if (!that.isScanning) { that.curInsertIndex = -1 that.curCoverIndex = -1 } } }, selectManyImage: function (image, index) { var that = this if (image.base64 == null || image.base64 == undefined || image.base64.length == 0) { //需要先加载原图才能正确操作图像 that.eleLoadding() that.WebScanController.loadImage(index, function (oriImageInfo) { console.log('加载原图成功 index:' + index) that.eleUnloadding() that.urls[index].base64 = oriImageInfo.image_base64 that.selectManyImage(that.urls[index], index) }) } else { this.selectImageObj = { "image": image, "index": index } var indexof = this.selectManyImages.indexOf(index); if (indexof >= 0) {//原本就是选中了 var nextIndex = indexof + 1; if (nextIndex < this.selectManyImages.length) {//小于最大,那就选中最大index var index = this.selectManyImages[nextIndex]; this.selectImageObj = { "image": this.urls[index], "index": index } this.loadImageToCanvas(this.urls[index]); } else {//取消选中最后一个index var preIndex = indexof - 1; if (preIndex >= 0) { var index = this.selectManyImages[preIndex]; this.selectImageObj = { "image": this.urls[index], "index": index } this.loadImageToCanvas(this.urls[index]); } else {//一个都不选了 this.loadImageToCanvas(null); $(".canvas-container").css("border", "none"); } } this.selectManyImages.splice(indexof, 1); } else {//选中原本未选中的 this.selectManyImages.push(index); this.loadImageToCanvas(image); } } }, addOptActive: function (e) { if (e == null || e == undefined) { return; } $(e.currentTarget).addClass("active"); $(e.currentTarget).siblings().removeClass("active"); }, //图片大小自适应 ajustDimensions: function ($event) { if (this.image == null || this.image == undefined) { this.$message.warning('请选择图像进行操作'); return; } this.addOptActive($event); this.clearDivListener(); var width = $("#canvas-container").width() - 4; var height = $("#canvas-container").height() - 4; var zoom = Math.min(width / this.image.width, height / this.image.height); //图像缩放 if (width > this.image.width && height > this.image.height) { width = this.image.width; height = this.image.height } else if (zoom < 1) { width = this.image.width * zoom; height = this.image.height * zoom; } //判断是否需要横放 var oldEven = (this.totalAngle / 90) % 2; if (oldEven != 0 && this.totalAngle % 90 == 0) { this.canvas.setDimensions({ width: height, height: width }) } else { this.canvas.setDimensions({ width: width, height: height }) } this.canvas.setZoom(zoom); this.scale = zoom; this.canvas.renderAll.bind(this.canvas); this.clearDivListener(); }, loadImageToCanvas: function (imageSrc, realDimensions) { this.clearDivListener() this.canvas.clear() this.canvas.setZoom(1) this.scale = 1 this.angle = 0 this.totalAngle = 0 this.canvas.discardActiveObject() var that = this // console.log('准备加载图像到画布:' + JSON.stringify(imageSrc)) new fabric.Image.fromURL(imageSrc ? imageSrc.base64 : null, function (image) { // console.log('加载图像:image===' + image) var result = imageSrc ? image : null that.image = result that.canvas.add(image) if (realDimensions) { that.realDimensions(null, false) } else { //太小了还是展示原图 if (image.width < 1200 || image.height < 1200) { that.realDimensions(null, false) } else { that.ajustDimensions() } } }, { selectable: false }) $(".canvas-container").css("border", "2px solid #e1e1e1") }, //图片实际大小 realDimensions: function ($event, withActive) { if (withActive) { if (this.image == null || this.image == undefined) { this.$message.warning('请选择图像进行操作'); return; } this.addOptActive($event); this.clearDivListener(); } var that = this; //判断是否需要横放 var oldEven = (this.totalAngle / 90) % 2; if (oldEven != 0 && this.totalAngle % 90 == 0) { this.canvas.setDimensions({ width: that.image.height, height: that.image.width }) } else { this.canvas.setDimensions({ width: that.image.width, height: that.image.height }) } this.canvas.setZoom(1); this.canvas.renderAll.bind(this.canvas); }, addListenerToDiv: function ($event) { this.addOptActive($event); this.clearDivListener(); var that = this; var startX = 0; var startY = 0; this.canvas.defaultCursor = 'pointer'; this.canvas.hoverCursor = 'pointer'; $("#canvas-container").bind("mousedown", function (e) { startX = e.offsetX; startY = e.offsetY; that.canvas.selection = false; $("#canvas-container").bind("mousemove", function (e) { var endX = e.offsetX; var endY = e.offsetY; var offsetX = startX - endX; var offsetY = startY - endY; //获取现在X的滚动长度 var scrollY = $(this).scrollTop(); //获取当前Y的滚动长度 var scrollX = $(this).scrollLeft(); $(this).scrollLeft(scrollX + offsetX); $(this).scrollTop(scrollY + offsetY); }); }); $("#canvas-container").bind("mouseup", function (e) { $(this).unbind("mousemove"); }); }, clearDivListener: function () { $("#canvas-container").unbind("mouseup"); $("#canvas-container").unbind("mousedown"); this.canvas.defaultCursor = 'default'; this.canvas.hoverCursor = 'default'; this.canvas.off("mouse:down"); this.canvas.off("mouse:up"); this.canvas.off("mouse:move"); this.canvas.off("mouse:dblclick"); this.rectificationDialog = false this.showWaterMarkPosition = false this.showWaterMark = false }, //图像拆分 split: function (isHorizontal, $event) { if (this.selectImageObj == null || this.selectImageObj.image == null || this.selectImageObj.image == undefined) { this.eleMessage("请选择要切分的文件", "warning"); return; } if (!this.checkCanDo()) { return; } this.clearDivListener(); this.addOptActive($event); var that = this; var fontSize = 18; var zoom = this.canvas.getZoom(); fontSize = fontSize / zoom; this.canvas.on("mouse:down", function (ev) { var pointer = that.canvas.getPointer(ev); if (isHorizontal) { that.assistLine = new fabric.Line([pointer.x, 0, pointer.x, that.image.height], { fill: 'red', stroke: 'red', //笔触颜色 strokeWidth: 2,//笔触宽度 selectable: false }); that.assistText = new fabric.IText('双击进行切分', { left: pointer.x + 10, top: pointer.y, fill: '#ff0000', fontSize: fontSize, selectable: false }); that.canvas.add(that.assistText); that.canvas.add(that.assistLine); } else { that.assistLine = new fabric.Line([0, pointer.y, that.image.width, pointer.y], { fill: 'red', stroke: 'red', //笔触颜色 strokeWidth: 2,//笔触宽度 selectable: false }); that.canvas.add(that.assistLine); that.assistText = new fabric.IText('双击进行切分', { left: pointer.x + 10, top: pointer.y + 10, fill: '#ff0000', fontSize: fontSize, selectable: false }); that.canvas.add(that.assistText); } that.canvas.on("mouse:move", function (event) { that.canvas.off("mouse:down"); var movepointer = that.canvas.getPointer(event); that.canvas.remove(that.assistLine); that.canvas.remove(that.assistText); if (isHorizontal) { that.assistLine = new fabric.Line([movepointer.x, 0, movepointer.x, that.image.height], { fill: 'red', stroke: 'red', //笔触颜色 strokeWidth: 2,//笔触宽度 selectable: false }); that.assistText = new fabric.IText('双击进行切分', { left: movepointer.x + 10, top: movepointer.y, fill: '#ff0000', fontSize: fontSize, selectable: false }); that.canvas.add(that.assistText); that.canvas.add(that.assistLine); } else { that.assistLine = new fabric.Line([0, movepointer.y, that.image.width, movepointer.y], { fill: 'red', stroke: 'red', //笔触颜色 strokeWidth: 2,//笔触宽度 selectable: false }); that.assistText = new fabric.IText('双击进行切分', { left: movepointer.x + 10, top: movepointer.y + 10, fill: '#ff0000', fontSize: fontSize, selectable: false }); that.canvas.add(that.assistText); that.canvas.add(that.assistLine); } }) that.canvas.on("mouse:dblclick", function (ev) { that.$confirm('文件拆分后不可撤销, 是否继续?', '拆分', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', callback: function (value) { if (value == "confirm") { that.clearDivListener(); that.eleLoadding(); console.log('x1:' + that.assistLine.x1, 'y1:' + that.assistLine.y1, 'x2:' + that.assistLine.x2, 'y2:' + that.assistLine.y2) var currentIndex = that.selectImageObj.index var location = Math.floor(isHorizontal ? that.assistLine.x1 : that.assistLine.y1) console.log('location:' + location) that.WebScanController.splitImage(currentIndex, isHorizontal ? 'horz' : 'vert', location, function (info) { console.log('拆分图像成功:' + JSON.stringify(info)) that.eleUnloadding() that.clearCanvasData() if (info.image_base64_list.length == 2) { var firstBase64 = info.image_base64_list[0] var secondBase64 = info.image_base64_list[1] var firstPath = info.image_path_list[0] var secondPath = info.image_path_list[1] that.WebScanController.modifyImage(currentIndex, secondBase64, {}, function (info) { console.log('图像拆分:第二张修改成功...') that.urls[currentIndex] = { base64: secondBase64, thumbnail: secondBase64, path: secondPath } that.WebScanController.insertImage(firstBase64, currentIndex, function (info) { console.log('图像拆分:第一张插入成功...') that.eleMessage('图像拆分成功!') that.urls.splice(currentIndex, 0, { base64: firstBase64, thumbnail: firstBase64, path: firstPath }) }) }) } else { that.eleMessage('图像返回异常!') } }) } else { that.canvas.remove(that.assistLine); that.canvas.remove(that.assistText); } } }); }) }) }, clearCanvasData: function () { this.image = null this.selectImageObj = {index: -1} this.undoStack.length = 0; this.redoStack.length = 0; }, scaleMax: function ($event) { // var height = this.$refs.canvasContainer.offsetHeight; // var width = this.$refs.canvasContainer.offsetWidth; if (this.image == null || this.image == undefined) { this.$message.warning('请选择图像进行操作'); return; } this.addOptActive($event); this.clearDivListener(); var offset = 0.1; var scale = this.scale; scale += offset; var canvasWidth = this.image.width * scale; var canvasHeight = this.image.height * scale; var oldEven = (this.totalAngle / 90) % 2; if (oldEven != 0 && this.totalAngle % 90 == 0) { this.canvas.setDimensions({ width: canvasHeight, height: canvasWidth }) } else { this.canvas.setDimensions({ width: canvasWidth, height: canvasHeight }) } this.canvas.setZoom(scale); this.scale = scale; }, scaleMin: function ($event) { // var height = this.$refs.canvasContainer.offsetHeight; // var width = this.$refs.canvasContainer.offsetWidth; if (this.image == null || this.image == undefined) { this.$message.warning('请选择图像进行操作'); return; } this.addOptActive($event); this.clearDivListener(); var offset = 0.1; var scale = this.scale; scale -= offset; if (scale < 0.1) { scale = 0.1; } var canvasWidth = this.image.width * scale; var canvasHeight = this.image.height * scale; var oldEven = (this.totalAngle / 90) % 2; if (oldEven != 0 && this.totalAngle % 90 == 0) { this.canvas.setDimensions({ width: canvasHeight, height: canvasWidth }) } else { this.canvas.setDimensions({ width: canvasWidth, height: canvasHeight }) } this.canvas.setZoom(scale); this.scale = scale; }, rotate: function (rotate, $event) { if (this.image == null || this.image == undefined) { this.$message.warning('请选择图像进行操作'); return; } if ($event != undefined) { this.addOptActive($event); } this.clearDivListener(); this.redoStack.length = 0; this.rotateAngle(rotate); //添加undo var undo = { "type": 'rotate', "angle": rotate } this.undoStack.push(undo); }, rotateAngle: function (rotate) { if (!this.image) { return } var that = this; // this.angle+=rotate; var zoom = this.canvas.getZoom(); var group = new fabric.ActiveSelection(this.canvas.getObjects(), { selectable: false, hasBorders: false, hasControls: false, centeredRotation: true, originX: "center", originY: "center" }); this.totalAngle += rotate; group.rotate(rotate); //旋转后的角度 var oldEven = (this.totalAngle / 90) % 2; if (oldEven != 0 && this.totalAngle % 90 == 0) { //设置group偏移 group.set({ left: this.image.height / 2, top: this.image.width / 2 }); this.canvas.setDimensions({ width: this.image.height * zoom, height: this.image.width * zoom }); } else { group.set({ left: this.image.width / 2, top: this.image.height / 2 }); // console.log(group.getCenterPointer()); // console.log(that.image.width/2+","+this.imageHeight/2); this.canvas.setDimensions({ width: this.image.width * zoom, height: this.image.height * zoom }); this.canvas.setBackgroundColor("#ffffff"); } this.canvas.renderAll(); group.destroy(); }, rectification: function ($event) {// 纠偏 if (this.image == null || this.image == undefined) { this.$message.warning('请选择图像进行操作'); return; } if ($event != undefined) { this.addOptActive($event); } this.clearDivListener(); this.rectificationDialog = true; this.repSliderValue = 0; }, sliderRotateChange: function (value) { var that = this; var rotate = value - this.angle; this.angle = value; this.redoStack.length = 0; this.rotateAngle(rotate); //添加undo var undo = { "type": 'rotate', "angle": rotate } this.undoStack.push(undo); }, innerErase: function ($event) { if (this.image == null || this.image == undefined) { this.$message.warning('请选择图像进行操作'); return; } this.addOptActive($event); this.clearDivListener(); var that = this; this.redoStack.length = 0; // this.canvas.discardActiveObject(); var that = this; this.canvas.hoverCursor = 'crosshair'; this.canvas.defaultCursor = 'crosshair'; this.canvas.selection = true; this.canvas.on("mouse:down", function (e) { that.startP = that.canvas.getPointer(e); }) that.canvas.on("mouse:up", function (e) { var endPointer = that.canvas.getPointer(e); if (endPointer.x == that.startP.x && endPointer.y == that.startP.y) { return; } //计算开始结束点和范围 var width = endPointer.x - that.startP.x; var height = endPointer.y - that.startP.y; if (width < 0) { width = -width; } if (height < 0) { height = -height; } var startLeft = that.startP; if (endPointer.x < startLeft.x) { startLeft.x = endPointer.x; } if (endPointer.y < startLeft.y) { startLeft.y = endPointer.y; } //添加矩形区域 var rect = new fabric.Rect({ fill: 'rgb(255,255,255)', hasBorders: false, hasControls: false, left: startLeft.x, top: startLeft.y, width: width, height: height, preserveObjectStacking: true, selectable: false }) that.canvas.add(rect); var objects = new Array(); objects.push(rect); var undo = { "type": 'addObjects', "objects": objects } that.undoStack.push(undo); }); }, outerErase: function ($event) { if (this.image == null || this.image == undefined) { this.$message.warning('请选择图像进行操作'); return; } this.redoStack.length = 0; this.addOptActive($event); this.clearDivListener(); var that = this; // this.canvas.discardActiveObject(); this.canvas.hoverCursor = 'crosshair'; this.canvas.selection = true; this.canvas.on("mouse:down", function (e) { that.startP = that.canvas.getPointer(e); }) that.canvas.on("mouse:up", function (e) { var endPointer = that.canvas.getPointer(e); if (endPointer.x == that.startP.x && endPointer.y == that.startP.y) { return; } //计算开始结束点和范围 var width = endPointer.x - that.startP.x; width = width < 0 ? -width : width; var height = endPointer.y - that.startP.y; height = height < 0 ? -height : height; var startP = {x: that.startP.x, y: that.startP.y}; var endP = {x: endPointer.x, y: endPointer.y} if (endPointer.x < that.startP.x) { startP.x = endPointer.x; endP.x = that.startP.x; } if (endPointer.y < that.startP.y) { startP.y = endPointer.y; endP.y = that.startP.y; } var objects = new Array(); //区域外的地方设置为透明 var rectTop = new fabric.Rect({ fill: 'rgb(255,255,255)', hasBorders: false, hasControls: false, left: 0, top: 0, width: that.image.width, height: startP.y, selectable: false }) that.canvas.add(rectTop); objects.push(rectTop); var rectLeft = new fabric.Rect({ fill: 'rgb(255,255,255)', hasBorders: false, hasControls: false, left: 0, top: 0, width: startP.x, height: that.image.height, selectable: false }) that.canvas.add(rectLeft); objects.push(rectLeft); var rectBottom = new fabric.Rect({ fill: 'rgb(255,255,255)', hasBorders: false, hasControls: false, left: 0, top: endP.y, width: that.image.width, height: that.image.height - endP.y, selectable: false }) that.canvas.add(rectBottom); objects.push(rectBottom); var rectRight = new fabric.Rect({ fill: 'rgb(255,255,255)', hasBorders: false, hasControls: false, left: endP.x, top: 0, width: that.image.width - endP.x, height: that.image.height, selectable: false }) that.canvas.add(rectRight); objects.push(rectRight); var undo = { "type": 'addObjects', "objects": objects } that.undoStack.push(undo); }); }, undo: function ($event) { if (this.undoStack.length <= 0) { return false; } this.addOptActive($event); this.clearDivListener(); var undo = this.undoStack.pop(); if (undo == undefined) { return false; } if (undo.type == 'rotate') { var rotate = undo.angle; this.rotateAngle(-rotate); //添加redo var redo = { "type": "rotate", "angle": -rotate } this.redoStack.push(redo); } if (undo.type == 'addObjects') { var objects = undo.objects; if (objects != null && objects.length > 0) { for (var i = 0; i < objects.length; i++) { var obj = objects[i]; this.canvas.remove(obj); } } var redo = { "type": "addObjects", "objects": objects } this.redoStack.push(redo); } }, redo: function ($event) { if (this.redoStack.length <= 0) { return false; } this.addOptActive($event); this.clearDivListener(); var that = this; var redo = this.redoStack.pop(); if (redo.type == 'rotate') { var rotate = redo.angle; this.rotateAngle(-rotate); //添加redo var undo = { "type": "rotate", "angle": -rotate } this.undoStack.push(undo); } if (redo.type == 'addObjects') { var objects = redo.objects; if (objects != null && objects.length > 0) { for (var i = 0; i < objects.length; i++) { var obj = objects[i]; this.canvas.add(obj); } } var undo = { "type": "addObjects", "objects": objects } this.undoStack.push(undo); } }, save: function () { // if (this.selectImageObj == null || this.selectImageObj.base64 == '') { // this.eleMessage("请选择图像", "warning"); // return; // } if (this.image == null || this.image == undefined) { this.$message.warning('请选择图像进行操作'); return; } this.clearDivListener(); var zoom = this.canvas.getZoom(); zoom = 1 / zoom; var dataUrl = this.canvas.toDataURL({ format: 'jpeg', multiplier: zoom, quality: 1 }); var that = this; this.eleLoadding(); // console.log('save image dataUrl:' + dataUrl) var currIndex = this.selectImageObj.index this.WebScanController.modifyImage(currIndex, dataUrl, {}, function (info) { console.log('修改图像成功:' + JSON.stringify(info)) that.eleUnloadding() that.undoStack.length = 0; that.redoStack.length = 0; //获取选中的一张重新赋值 // that.selectImageObj.image.base64 = dataUrl; that.urls[currIndex].thumbnail = dataUrl that.urls[currIndex].base64 = dataUrl that.selectImage(that.urls[currIndex], currIndex) }) }, //显示水印配置框 showWaterMarkConfigure: function ($event) { if (this.selectImageObj == null || this.selectImageObj.image == null || this.selectImageObj.image == undefined) { this.eleMessage("请选择要操作的文件", "warning"); return; } this.clearDivListener(); this.addOptActive($event); this.markFontName = this.waterMarkInfo.font_name this.markFontSize = this.waterMarkInfo.font_size this.markFontBold = this.waterMarkInfo.font_bold this.markFontUnderline = this.waterMarkInfo.font_underline this.markFontItalic = this.waterMarkInfo.font_italic this.markFontStrikeout = this.waterMarkInfo.font_strikeout this.waterMarkText = this.waterMarkInfo.text this.markFontColor = this.waterMarkInfo.text_color this.showWaterMark = true if (this.assistText != null) { this.canvas.remove(this.assistText) } // if (this.markText != null) { // this.canvas.remove(this.markText) // } }, //水印文字配置完成 confirmMarkConfigure: function () { this.showWaterMark = false this.waterMarkInfo.font_name = this.markFontName this.waterMarkInfo.font_size = this.markFontSize this.waterMarkInfo.font_bold = this.markFontBold this.waterMarkInfo.font_underline = this.markFontUnderline this.waterMarkInfo.font_italic = this.markFontItalic this.waterMarkInfo.font_strikeout = this.markFontStrikeout this.waterMarkInfo.text = this.waterMarkText this.waterMarkInfo.text_color = this.markFontColor console.log('font_size:' + this.waterMarkInfo.font_size, 'fontStyle:' + this.waterMarkInfo.font_italic, 'underline:' + this.waterMarkInfo.font_underline, 'linethrough:' + this.waterMarkInfo.font_strikeout, 'fontWeight:' + this.waterMarkInfo.font_bold) this.addWaterMark() }, //往canvas添加文字水印 addBySelf是否自行实现水印该功能 addWaterMark: function () { this.realDimensions(null, false) this.showWaterMarkPosition = true this.markPositionTipX = 0 this.markPositionTipY = 0 var that = this var fontSize = this.waterMarkInfo.font_size var textColor = this.markFontColor var fontStyle = 'normal' if (this.waterMarkInfo.font_italic == true) { fontStyle = 'italic' } var underline = false if (this.waterMarkInfo.font_underline == true) { underline = true } var linethrough = false if (this.waterMarkInfo.font_strikeout == true) { linethrough = true } var fontWeight = 'normal' if (this.waterMarkInfo.font_bold == true) { fontWeight = 'bold' } console.log('font_size:' + fontSize, 'fontStyle:' + fontStyle, 'underline:' + underline, 'linethrough:' + linethrough, 'fontWeight:' + fontWeight) var zoom = this.canvas.getZoom() fontSize = fontSize * zoom this.canvas.on("mouse:down", function (ev) { var pointer = that.canvas.getPointer(ev) if (that.assistText != null) { that.canvas.remove(that.assistText) } // if (that.markText != null) { // that.canvas.remove(that.markText) // } that.assistText = new fabric.IText('双击进行添加', { left: pointer.x, top: pointer.y + fontSize + 10, fill: '#ff0000', fontSize: fontSize, selectable: false }) that.markText = new fabric.IText(that.waterMarkInfo.text, { left: pointer.x, top: pointer.y, fill: textColor, fontSize: fontSize, selectable: false, fontStyle: fontStyle, underline: underline, linethrough: linethrough, fontWeight: fontWeight, fontFamily: that.waterMarkInfo.font_name, }); that.canvas.add(that.assistText) that.canvas.add(that.markText) that.canvas.off("mouse:down") that.canvas.on("mouse:move", function (event) { var movepointer = that.canvas.getPointer(event); that.canvas.remove(that.assistText) that.canvas.remove(that.markText) that.assistText = new fabric.IText('双击进行添加', { left: movepointer.x, top: movepointer.y + fontSize + 10, fill: '#ff0000', fontSize: fontSize, selectable: false, }) that.markText = new fabric.IText(that.waterMarkInfo.text, { left: movepointer.x, top: movepointer.y, fill: textColor, fontSize: fontSize, selectable: true, fontStyle: fontStyle, underline: underline, linethrough: linethrough, fontWeight: fontWeight, fontFamily: that.waterMarkInfo.font_name, }) that.markPositionTipX = movepointer.x that.markPositionTipY = movepointer.y that.canvas.add(that.markText) that.canvas.add(that.assistText) }) that.canvas.on("mouse:dblclick", function (ev) { that.canvas.remove(that.assistText) that.clearDivListener() }) // that.canvas.on("mouse:dblclick", function (ev) { // // that.canvas.remove(that.assistText) // that.$confirm('水印添加后不可撤销, 是否继续?', '添加水印', { // confirmButtonText: '继续', // cancelButtonText: '取消', // type: 'warning' // } // ).then(() => { // that.clearDivListener() // that.eleLoadding(); // console.log('markText:' + JSON.stringify(that.markText)) // console.log('x1:' + that.markText.x1, 'y1:' + that.markText.y1, // 'x2:' + that.markText.x2, 'y2:' + that.markText.y2) // var currentIndex = that.selectImageObj.index // // // var zoom = that.canvas.getZoom() // zoom = 1 / zoom; // var dataUrl = that.canvas.toDataURL({ // format: 'jpeg', // multiplier: zoom, // quality: 1 // }); // that.eleLoadding() // console.log('save image dataUrl:' + dataUrl) // that.WebScanController.modifyImage(currentIndex, dataUrl, {}, function (info) { // that.eleUnloadding() // console.log('修改成功') // that.urls[currentIndex].base64 = dataUrl // that.urls[currentIndex].thumbnail = dataUrl // // that.undoStack.length = 0; // that.redoStack.length = 0; // that.loadImageToCanvas(that.urls[currentIndex]) // // //获取选中的一张重新赋值 // that.selectImageObj.image.base64 = dataUrl; // }) // } // ) // .catch(() => { // that.canvas.remove(that.markText); // that.canvas.remove(that.assistText); // }) // // }) }) }, //图片裁剪 cropImage: function ($event) { if (this.image == null || this.image == undefined) { this.$message.warning('请选择图像进行操作'); return; } if (!this.checkCanDo()) return; this.addOptActive($event); this.clearDivListener(); this.redoStack.length = 0; // this.canvas.discardActiveObject(); var that = this; this.canvas.hoverCursor = 'crosshair'; this.canvas.defaultCursor = 'crosshair'; this.canvas.selection = true; this.canvas.on("mouse:down", function (e) { that.startP = that.canvas.getPointer(e); }) that.canvas.on("mouse:up", function (e) { var endPointer = that.canvas.getPointer(e); if (endPointer.x == that.startP.x && endPointer.y == that.startP.y) { return; } that.$confirm('裁剪后不可撤销, 请选择保存类型', '图片裁剪', { distinguishCancelAndClose: true, confirmButtonText: '另存为', cancelButtonText: '覆盖原图' }) .then(() => { console.log('另存为') that.cropImageLogic($event, endPointer, false) }) .catch(action => { if (action === 'cancel') { console.log('覆盖保存') that.cropImageLogic($event, endPointer, true) } else { console.log('取消裁剪') } }); }); }, //真正的图片裁剪逻辑 coverSave:覆盖保存 cropImageLogic: function ($event, endPointer, coverSave) { var that = this that.eleLoadding() that.clearDivListener() var currentIndex = that.selectImageObj.index var endPointerX = endPointer.x var endPointerY = endPointer.y //限制一下范围 if (endPointerX < 0) { endPointerX = 0 } if (endPointerX > that.image.width) { endPointerX = that.image.width } if (endPointerY < 0) { endPointerY = 0 } if (endPointerY > that.image.height) { endPointerY = that.image.height } //实际选择的图片像素 var width = Math.abs(endPointerX - that.startP.x); var height = Math.abs(endPointerY - that.startP.y); var canvasWidth = $("#canvas-container").width(); var canvasHeight = $("#canvas-container").height(); //实际图片宽度/展示出来的宽度 var zoom = that.image.width / that.canvas.width; var startLeft = that.startP; startLeft.x = Math.min(endPointerX, startLeft.x) startLeft.y = Math.min(endPointerY, startLeft.y) console.log('scale:' + zoom) var targetStartX = startLeft.x / zoom var targetStartY = startLeft.y / zoom var targetWidth = width / zoom var targetHeight = height / zoom console.log('left top:' + targetStartX + ' ' + targetStartY + ' width:' + targetWidth + ' height:' + targetHeight) console.log('canvas width:' + canvasWidth + ' canvas height:' + canvasHeight + ' canWidth:' + that.canvas.width + ' canHeight:' + that.canvas.height) console.log('image width:' + that.image.width + ' image height:' + that.image.height) var croppedImage = that.canvas.toDataURL({ left: targetStartX, // 指定区域左上角的x坐标 top: targetStartY, // 指定区域左上角的y坐标 width: targetWidth, // 指定区域的宽度 height: targetHeight, // 指定区域的高度 }); new fabric.Image.fromURL(croppedImage, function (result) { that.image = result if (coverSave) { //覆盖保存 that.WebScanController.modifyImage(currentIndex, croppedImage, {}, function (info) { that.eleUnloadding() console.log('图片裁剪修改成功') that.urls[currentIndex].base64 = croppedImage that.urls[currentIndex].thumbnail = croppedImage //获取选中的一张重新赋值 that.selectImageObj.image.base64 = croppedImage; that.undoStack.length = 0; that.redoStack.length = 0; that.loadImageToCanvas(that.urls[currentIndex], true) }) } else { //另存为 that.WebScanController.insertImage(croppedImage, currentIndex + 1, function (insertInfo) { that.eleUnloadding() console.log('图像裁剪另存为:插入图片成功') // {"func":"insert_image","iden":"gE/rN4vZATMg49y/OCFlZA==","ret":0} that.urls.splice(currentIndex + 1, 0, { thumbnail: croppedImage, base64: croppedImage }) that.undoStack.length = 0; that.redoStack.length = 0; that.selectImage(that.urls[currentIndex + 1], currentIndex + 1) }) } }, { selectable: false }) }, checkCanDo: function () { if (this.undoStack.length > 0) { this.$alert('请先保存对图片的修改', '提示', { confirmButtonText: '确定', type: 'warning', }); return false } else { return true } }, /******************************************* ***************************************************************/ formatJson: function () { console.log('formatJson:' + this.originJson) try { const jsonObj = JSON.parse(this.originJson); this.formatedJson = JSON.stringify(jsonObj, null, 4); } catch (e) { this.formatedJson = e } }, eleLoadding: function () { this.fullscreenLoading = true }, eleUnloadding: function () { this.fullscreenLoading = false }, eleMessage: function (msg, sign) { var type = sign ? sign : 'success' var message = msg ? msg : '未知异常' this.$message({ message: message, type: type, duration: 2000 }); }, randomRange: function (min, max) { // min最小值,max最大值 return Math.floor(Math.random() * (max - min)) + min; }, parameterTranslation: function (originalValue) { var value switch (originalValue) { case "color": value = "彩色" break; case "gray": value = "灰度" break; case "binary": value = "二进制" break; case "auto": value = "自动" break; case "simplex": value = "单面" break; case "duplex": value = "双面" break; case "filter_blank_general": value = "filter_blank_general" break; case "filter_blank_invoice": value = "filter_blank_invoice" break; case "fold_in_half": value = "fold_in_half" break; case "auto": value = "匹配原始尺寸" break; case "a3": value = "A3" break; case "a4": value = "A4" break; case "a4_horz": value = "A4横向" break; case "image_tiff_compression": value = "tiff压缩方式" break; case "image_tiff_compression": value = "tiff压缩质量" break; default: value = originalValue break } return value }, parameterCoerceIn: function () { var paramsRange = this.scanParamsRange this.scanParams = new Array() for (var i = 0; i < paramsRange.length; i++) { var group = paramsRange[i] var newGroup = { group_name: group.group_name, group_param: new Array() } for (var j = 0; j < group.group_param.length; j++) { newGroup.group_param.push({ name: group.group_param[j].name, value: group.group_param[j].value }) } this.scanParams.push(newGroup) } // console.log('当前扫描参数:' + JSON.stringify(this.scanParams)) // console.log('当前强强强扫描参数:' + JSON.stringify(paramsRange)) this.$forceUpdate() }, // 将base64转换为blob dataURLtoBlob: function (dataUrl) { var data if (dataUrl.indexOf(',') != -1) { data = dataUrl.split(',')[1] } else { data = dataUrl } var bstr = atob(data) var n = bstr.length var u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } return new Blob([u8arr]) }, // 将blob转换为file blobToFile: function (theBlob, fileName) { theBlob.lastModifiedDate = new Date() theBlob.name = fileName return theBlob }, downloadBase64File: function (base64, fileName) { var blob = this.dataURLtoBlob(base64) if (window.navigator.msSaveOrOpenBlob) { navigator.msSaveBlob(blob, fileName) } else { this.blobToFile(blob, fileName) var aLink = document.createElement('a') document.body.appendChild(aLink) var evt = document.createEvent("HTMLEvents") evt.initEvent("click", true, true) aLink.download = fileName aLink.href = URL.createObjectURL(blob) aLink.click() document.body.removeChild(aLink) } }, // clearLog() { // this.socketMsg = '' // }, // appendLog(msg) { // this.socketMsg = this.socketMsg + this.showtime() + ' ' + msg + '\n' // // this.$nextTick(function () { // if (this.$refs.logArea) { // this.$refs.logArea.scrollTop = this.$refs.logArea.scrollHeight // } // }) // }, // sendSocketCommand: function () { // if (this.socketCommand.length != 0) { // try { // JSON.parse(this.socketCommand); // // const socketCommand = JSON.stringify(this.socketCommand) // } catch (e) { // const err = 'json format err:' + e // // this.appendLog(err) // console.log(err) // return // } // console.log('sendSocketCommand:' + this.socketCommand) // this.WebScanController.sendCommand(JSON.parse(this.socketCommand)) // // this.appendLog('send socket command:' + this.socketCommand) // } else { // const msg = 'sendSocketCommand: command is empty!!!' // // this.appendLog(msg) // console.log(msg) // } // }, // showtime: function () { // const date = new Date(); // var h = this.checkTime(date.getHours()) // var m = this.checkTime(date.getMinutes()) // var s = this.checkTime(date.getSeconds()) // return h + ":" + m + ":" + s // }, // checkTime: function (i) { // if (i < 10) { // i = "0" + i; // } // return i; // }, showBigImage: function (index) { console.log('showBigImage:' + index) if (this.urls[index].base64 == null || this.urls[index].base64 == undefined || this.urls[index].base64.length == 0) { var that = this this.WebScanController.loadImage(index, function (origImageInfo) { console.log('加载原图成功!') that.urls[index].base64 = origImageInfo.image_base64 that.showBigImage(index) }) } else { this.selectBigImage = this.urls[index].base64 this.showBigImageDialog = true } }, } })