konva Image 对上报不同数据格式,客户端处理方式

2024-08-29 22:04

本文主要是介绍konva Image 对上报不同数据格式,客户端处理方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

vue3组件

<v-stageid="konva_stage":config="konvaConfig"ref="konvaStageRef"@wheel="wheelForScale($event)"><v-layer><v-group :config="group"><v-image:config="{image: pgmImage,}"/></v-group></v-layer></v-stage>


1. Blob 对象(推荐)


if (data instanceof Blob) {const url = URL.createObjectURL(data);pgmImage.value = new Image();pgmImage.value.src = url;pgmImage.value.onload = function () {console.log("pgmImage.width", pgmImage.value.naturalWidth);console.log("pgmImage.height", pgmImage.value.naturalHeight);};
}

2.base64(此种方式,读取图片内容转换成base64格式会比原图片大大概1/3)

const base64Str = imgData; // imgData 从后端接口或者websocket 上报数据
pgmImage.value = new Image();
pgmImage.value.src = base64Str;
pgmImage.value.onload = ()=> {// 获取图片参数 参与逻辑操作
}

3. pgm 这种非常不推荐pgm本身比其他图片格式大,且不能压缩处理,对图片较大情况下非常不友好!

解析接口传递过来的pgm 数据

const MapImage = function (data) {let exp = /^(\S+)\s+(\#.*?\n)*\s*(\d+)\s+(\d+)\s+(\d+)?\s*/;let match = data && data.match(exp);if (match) {let width = (this.width = parseInt(match[3], 10));let height = (this.height = parseInt(match[4], 10));let maxVal = parseInt(match[5], 10);let bytes = maxVal < 256 ? 1 : 2;let imgData = data.substr(match[0].length);switch (match[1]) {case "P1":this._parser = new ASCIIParser(maxVal + " " + imgData, bytes);this._formatter = new PBMFormatter(width, height);break;case "P2":this._parser = new ASCIIParser(imgData, bytes);this._formatter = new PGMFormatter(width, height, maxVal);break;case "P3":this._parser = new ASCIIParser(imgData, bytes);this._formatter = new PPMFormatter(width, height, maxVal);break;case "P4":this._parser = new BinaryParser(imgData, bytes);this._formatter = new PBMFormatter(width, height);break;case "P5":this._parser = new BinaryParser(imgData, bytes);this._formatter = new PGMFormatter(width, height, maxVal);break;case "P6":this._parser = new BinaryParser(data, bytes);this._formatter = new PPMFormatter(width, height, maxVal);break;default:throw new TypeError("Sorry, your file format is not supported. [" + match[1] + "]");}} else {throw new TypeError("Sorry, file does not appear to be a Netpbm file.");}
};MapImage.prototype.getInitMap = function (type = "image") {let canvas = this._formatter.getPainting(this._parser, type);return canvas;
};const BinaryParser = function (data, bytes) {this._data = data;this._bytes = bytes;this._pointer = 0;
};BinaryParser.prototype.getNextSample = function () {if (this._pointer >= this._data.length) return false;let val = 0;for (let i = 0; i < this._bytes; i++) {val = val * 255 + this._data.charCodeAt(this._pointer++);}return val;
};const ASCIIParser = function (data, bytes) {this._data = data.split(/\s+/);this._bytes = bytes;this._pointer = 0;
};ASCIIParser.prototype.getNextSample = function () {if (this._pointer >= this._data.length) return false;let val = 0;for (let i = 0; i < this._bytes; i++) {val = val * 255 + parseInt(this._data[this._pointer++], 10);}return val;
};const PPMFormatter = function (width, height, maxVal) {this._width = width;this._height = height;this._maxVal = maxVal;
};PPMFormatter.prototype.getPainting = function (parser, type) {let paintData = null;let canvas = null;let ctx = null;let img = null;if (type === "canvas") {canvas = document.createElement("canvas");ctx = canvas.getContext("2d");canvas.width = ctx.width = this._width;canvas.height = ctx.height = this._height;paintData = ctx.getImageData(0, 0, this._width, this._height);} else {paintData = new Uint8ClampedArray(this._width * this._height * 4);}let dataArr = type === "canvas" ? paintData.data : paintData;for (let row = 0; row < this._height; row++) {for (let col = 0; col < this._width; col++) {let factor = 255 / this._maxVal;let r = factor * parser.getNextSample();let g = factor * parser.getNextSample();let b = factor * parser.getNextSample();let pos = (row * this._width + col) * 4;dataArr[pos] = r;dataArr[pos + 1] = g;dataArr[pos + 2] = b;dataArr[pos + 3] = 255;}}if (type === "canvas") {ctx.putImageData(paintData, 0, 0);return canvas;} else {img = new ImageData(paintData, this._width, this._height);return img;}
};const PGMFormatter = function (width, height, maxVal) {this._width = width;this._height = height;this._maxVal = maxVal;
};PGMFormatter.prototype.getPainting = function (parser, type) {let paintData = null;let canvas = null;let ctx = null;let img = null;if (type === "canvas") {canvas = document.createElement("canvas");ctx = canvas.getContext("2d");canvas.width = ctx.width = this._width;canvas.height = ctx.height = this._height;paintData = ctx.getImageData(0, 0, this._width, this._height);} else {paintData = new Uint8ClampedArray(this._width * this._height * 4);}let dataArr = type === "canvas" ? paintData.data : paintData;for (let row = 0; row < this._height; row++) {for (let col = 0; col < this._width; col++) {let d = parser.getNextSample() * (255 / this._maxVal);let pos = (row * this._width + col) * 4;dataArr[pos] = d;dataArr[pos + 1] = d;dataArr[pos + 2] = d;dataArr[pos + 3] = 255;}}if (type === "canvas") {ctx.putImageData(paintData, 0, 0);return canvas;} else {img = new ImageData(paintData, this._width, this._height);return img;}
};const PBMFormatter = function (width, height) {this._width = width;this._height = height;
};PBMFormatter.prototype.getPainting = function (parser, type) {let paintData = null;let canvas = null;let ctx = null;let img = null;if (type === "canvas") {canvas = document.createElement("canvas");ctx = canvas.getContext("2d");canvas.width = ctx.width = this._width;canvas.height = ctx.height = this._height;paintData = ctx.getImageData(0, 0, this._width, this._height);}if (parser instanceof BinaryParser) {let data = "";let byte = null;let bytesPerLine = Math.ceil(this._width / 8);for (let i = 0; i < this._height; i++) {let line = parser._data.substr(i * bytesPerLine, bytesPerLine);let lineData = "";for (let j = 0; j < line.length; j++)lineData += ("0000000" + line.charCodeAt(j).toString(2)).substr(-8);data += lineData.substr(0, this._width);}while ((byte = parser.getNextSample()) !== false) {data += ("0000000" + byte.toString(2)).substr(-8);}parser = new ASCIIParser(data.split("").join(" "), 1);}let dataArr = type === "canvas" ? paintData.data : paintData;for (let row = 0; row < this._height; row++) {for (let col = 0; col < this._width; col++) {let d = (1 - parser.getNextSample()) * 255;let pos = (row * this._width + col) * 4;dataArr[pos] = d;dataArr[pos + 1] = d;dataArr[pos + 2] = d;dataArr[pos + 3] = 255;}}if (type === "canvas") {ctx.putImageData(paintData, 0, 0);return canvas;} else {img = new ImageData(paintData, this._width, this._height);return img;}
};export { MapImage };

vue2 使用方式:

if (pgmImageData) { //pgmImageData 接口返回let img = new MapImage(pgmImageData);let canvasImg = img.getInitMap("canvas");// canvasImg.width, canvasImg.heightthis.konvaConfig.pgmImage = new Image();this.konvaConfig.pgmImage.src = canvasImg.toDataURL();
}

这篇关于konva Image 对上报不同数据格式,客户端处理方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1118965

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

2. c#从不同cs的文件调用函数

1.文件目录如下: 2. Program.cs文件的主函数如下 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace datasAnalysis{internal static

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

uva 10061 How many zero's and how many digits ?(不同进制阶乘末尾几个0)+poj 1401

题意是求在base进制下的 n!的结果有几位数,末尾有几个0。 想起刚开始的时候做的一道10进制下的n阶乘末尾有几个零,以及之前有做过的一道n阶乘的位数。 当时都是在10进制下的。 10进制下的做法是: 1. n阶位数:直接 lg(n!)就是得数的位数。 2. n阶末尾0的个数:由于2 * 5 将会在得数中以0的形式存在,所以计算2或者计算5,由于因子中出现5必然出现2,所以直接一

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

用命令行的方式启动.netcore webapi

用命令行的方式启动.netcore web项目 进入指定的项目文件夹,比如我发布后的代码放在下面文件夹中 在此地址栏中输入“cmd”,打开命令提示符,进入到发布代码目录 命令行启动.netcore项目的命令为:  dotnet 项目启动文件.dll --urls="http://*:对外端口" --ip="本机ip" --port=项目内部端口 例: dotnet Imagine.M

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

【即时通讯】轮询方式实现

技术栈 LayUI、jQuery实现前端效果。django4.2、django-ninja实现后端接口。 代码仓 - 后端 代码仓 - 前端 实现功能 首次访问页面并发送消息时需要设置昵称发送内容为空时要提示用户不能发送空消息前端定时获取消息,然后展示在页面上。 效果展示 首次发送需要设置昵称 发送消息与消息展示 提示用户不能发送空消息 后端接口 发送消息 DB = []@ro

Thymeleaf:生成静态文件及异常处理java.lang.NoClassDefFoundError: ognl/PropertyAccessor

我们需要引入包: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>sp