mqtt传输图片并在网页上显示

  • 前言
  • 开源mqtt.js库
  • base64 编码
  • 模拟发送
  • web可视化

前言

由于最近在做水果识别系统,打算将识别出的结果传输到微信小程序,由于微信小程序限制太多,先在网页上进行实验

开源mqtt.js库

mqtt.js是一个开源的js库,而且兼容微信小程序,使用也比较简单,github网址mqtt.js,这里使用cdn的方式使用。

<script src="https://unpkg.com/mqtt@2.18.8/dist/mqtt.min.js"></script>

首先初始化信息

const options = {// 认证信息clientId: '设备id',username: '用户名',password: '密码',
}

然后进行连接

const client = mqtt.connect('ws://域名或ip:端口号/mqtt', options);

因为我使用的是自己搭建的mqtt服务端,没有域名,所以这里我选择ws方式,除了ws还有wss方式,两者的区别是ws不安全,wss较为安全,ws的默认端口为8083,wss默认端口为443

订阅主题

client.subscribe('主题名');

然后是发送

client.publish(topic, message, 可选q0s)

然后是接受函数

client.on('message', function (topic, message) {在这里处理
})

base64 编码

由于esp32的ram较小,只有512k,运行是用户可用的ram只剩200k左右,在传输图片是采用jpeg压缩,jpeg是一种有损压缩,压缩后可将图片体积大大减小,k210采集的图片为224224,如果采用rgb565,需要的大小大概为224224*2/1024=98k,这个大小对于esp32来说太大了,故在k210上对图片进行压缩,采用网上的一个c语言压缩代码,转换为jpg文件,压缩后大概15k。
压缩完成之后为二进制,二进制在传输过程中比较麻烦,一般为了传输方便都会对二进制流进行base64编码,base64编码完成之后可以完全用字符串表示
base64编码的原理就是将3个字节的内容用4个字节表示,可能这个时候就有些困惑,这不体积变大了吗?是的,编码后体积会变大三分之四,但是编码后传输更加方便
这里借鉴披荆又斩棘的讲解base64原理
在编码完之后所以的数据都可以用字符串表示,而且js可以直接显示base64流。下面为esp32 base64的编码代码

static const char *ALPHA_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";char *encode(const char *buf, const long size, char *base64Char) {int a = 0;int i = 0;while (i < size) {char b0 = buf[i++];char b1 = (i < size) ? buf[i++] : 0;char b2 = (i < size) ? buf[i++] : 0;int int63 = 0x3F; //  00111111int int255 = 0xFF; // 11111111base64Char[a++] = ALPHA_BASE[(b0 >> 2) & int63];base64Char[a++] = ALPHA_BASE[((b0 << 4) | ((b1 & int255) >> 4)) & int63];base64Char[a++] = ALPHA_BASE[((b1 << 2) | ((b2 & int255) >> 6)) & int63];base64Char[a++] = ALPHA_BASE[b2 & int63];}switch (size % 3) {case 1:base64Char[--a] = '=';case 2:base64Char[--a] = '=';}return base64Char;
}

模拟发送

由于我买杜邦线的时候全买成公对公的了,故现在只能模拟mqtt发送图片,这里我使用win画板做一幅图,然后使用python转换为.h文件
这里附赠一个简单的jpg转.h代码

import os
filename = 'test.jpg'
wd=[]
with open(filename, 'rb') as f:filename2= 'test.h'with open(filename2,'w+') as f2:k='const char test[]={'k2=','f2.write(str(k))size = os.path.getsize(filename) #获得文件大小 for i in range(size):m = f.read(1)n=int.from_bytes(m, byteorder='big', signed=False)f2.write(str(n))if i<size-1:f2.write(str(k2))print(i)i=i+1k='};'f2.write(str(k))f2.close()
f2.close()

转换之后jpg文件就变成了c语言的数组

int len=8842*4/3+1;
char* data = (char*) malloc(len);
char *base64=encode(test, 8842, data);
esp_mqtt_client_publish(client, "photo", (const char *)base64, len, 1, 0);

数组长度为8842,这里首先计算需要申请的内存大小,编码后为原文件的三分之四,然后进行编码,发送到photo主题。

接下来是js部分,创建一个div

<img src="apple.jpg" id="userImge" style="width: 50%;height:50%;" name="userImge" >

然后在client.on(‘message’, function (topic, message)mqtt接受函数里判断主题,并显示,在js里显示base64只需要一句代码

$("#userImge").attr("src","data:image/jpg;base64,"+p1);

web可视化

web可视化选用百度开源可视化库echarts,官方连接百度可视化库,因为是国人制作,里面的文档都挺详细,而且官方速度访问快多了,可以在官网在线修改。
上面有很多例程,基本涵盖需要的可视化工具。
最后附上一个简单的代码,这个代码是移动端布局,电脑布局排版会乱。如果没有服务器,想在手机上随时查看,可以放到github博客上运行。

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"><title>myProject</title><!-- 引入 js/echarts.min.js --><script src="js/echarts.min.js"></script><script src="https://unpkg.com/mqtt@2.18.8/dist/mqtt.min.js"></script><script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<style>
body{background:url("smart.jpg") no-repeat;background-size: 100%;
}
.t{margin-top:10%;
}
.div1{margin-top:70px;width:100%;display: flex;}
.div2{margin-left:5%;display: flex;}
</style>
</head>
<body><div class="t"><center><h1>水果分拣系统设计</h1></center></div><div class=div1><img src="apple.jpg" id="userImge" style="width: 50%;height:50%;" name="userImge" ><div style="width: 50%;height:200px;"><center><h3 >第<a id="num">0</a>个苹果</h3></center><center><h3>体积:中</h3></center><center><h3>成熟度:<a id="csd">85</a>%</h3></center><div class="div2"><center><button id="bu" style="width: 80px;height:30px">接收图片</button></center><center><button id="but" style="width: 80px;height:30px;margin-left:5%;">ledon</button></center></div></div></div><div id="dev" style="width: 100%;height:300px;"></div><script>//初始化仪表盘var myChart = new Array();var option = new Array();myChart = echarts.init(document.getElementById('dev'));option = {backgroundColor: '#2c343c',title: {text: '苹果数量统计',left: 'center',top: 20,textStyle: {color: '#ccc'}},tooltip: {trigger: 'item',formatter: '{a} <br/>{b} : {c} ({d}%)'},visualMap: {show: false,min: 80,max: 600,inRange: {colorLightness: [0, 1]}},series: [{name: '访问来源',type: 'pie',radius: '55%',center: ['50%', '50%'],data: [{value: 200, name: '大苹果'},{value: 100, name: '标准苹果'},{value: 100, name: '小苹果'},].sort(function (a, b) { return a.value - b.value; }),roseType: 'radius',label: {color: 'rgba(255, 255, 255, 0.3)'},labelLine: {lineStyle: {color: 'rgba(255, 255, 255, 0.3)'},smooth: 0.2,length: 10,length2: 20},itemStyle: {color: '#c23531',shadowBlur: 200,shadowColor: 'rgba(0, 0, 0, 0.5)'},animationType: 'scale',animationEasing: 'elasticOut',animationDelay: function (idx) {return Math.random() * 200;}}]
};
//初始化mqtt信息
const options = {// 认证信息clientId: '设备id',username: '用户名',password: '密码',
}const client = mqtt.connect('wss://域名:443/mqtt', options);
client.subscribe('up');
client.subscribe('photo');$("#bu").click(function(){str1="{\"id\":\"up\"}";client.publish("sw_led",str1,1);
});
$("#but").click(function(){var st=$("#but").text();console.log(st);if(st=="ledon"){str1="{\"id\":\"on\"}";client.publish("sw_led",str1,1);$("#but").text("ledoff");}else{str1="{\"id\":\"off\"}";client.publish("sw_led",str1,1);$("#but").text("ledon");}//str1="{\"id\":\"up\"}";// client.publish("sw_led",str1,1);
});
//myChart.setOption(option, true)
myChart.setOption(option, true)
//接受信息
client.on('message', function (topic, message) {var p1 = message.toString();//console.log(p1);if(topic=="up"){var p2 = JSON.parse(p1);console.log(p2);$("#csd").html(p2.val);option.series[0].data[0].value = p2.val;myChart.setOption(option, true)}else if(topic=="photo"){$("#userImge").attr("src","data:image/jpg;base64,"+p1);}})
client.on('reconnect', (error) => {console.log('正在重连:', error)
})
client.on('connect', (error) => {console.log('连接成功:', error)
})
client.on('error', (error) => {console.log('连接失败:', error)
})</script>
</body>
</html>

esp32学习 mqtt传输图片及数据可视化相关推荐

  1. Caffe学习系列(13):数据可视化环境(python接口)配置

    原文有更新: Caffe学习系列(13):数据可视化环境(python接口)配置 - denny402 - 博客园 http://www.cnblogs.com/denny402/p/5088399. ...

  2. matplotlib画图时间长_Python学习第86课-数据可视化之matplotlib介绍

    [每天几分钟,从零入门python编程的世界!] 我们得到数据之后,如何把数据可视化? 做研究的同学经常会用一个软件叫MATLAB,我们做数据可视化用一个库叫matplotlib,这个库跟MATLAB ...

  3. 深度学习数据驱动_利用深度学习实现手绘数据可视化的生成

    前一段时间,我开发了Sketchify, 该工具可以把任何以SVG为渲染技术的可视化转化为手绘风格.(参考手绘风格的数据可视化实现 Sketchify) 那么问题来了,很多的chart是以Canvas ...

  4. 爬虫学习案例3:数据可视化

    数据可视化 利用Flask框架将爬虫得到的数据展示在网页中,更为直观.以案例1中得到的数据为例进行可视化学习. 1.导入模块 from flask import Flask,render_templa ...

  5. Python数据科学学习笔记之——Matplotlib数据可视化

    Matplotlib 数据可视化 1.Matplotlib 常用技巧 1.1.导入 Matplotlib import matplotlib as mpl import matplotlib.pypl ...

  6. 学习之旅16-R数据可视化-图形处理(二)

    六.图形处理 前言 6.ggplot数据可视化 (二) 6.1 准备工作 6.2 图形映射 6.3 几何对象 6.4 统计变化 前言 上一节我们对ggplot2包中的高级绘图有了一定了解,但是里面的很 ...

  7. [LBS学习笔记 1]高德数据可视化初体验

    高德数据可视化初体验 背景 换了新工作,虽然还是java开发,但是之前搞做在线教育的,现在做地图相关的事.因此,花了些时间学了空间索引相关的内容,后期会写关于空间索引相关的内容,这期写地理数据可视化相 ...

  8. 利用深度学习实现手绘数据可视化的生成

    个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈 前一段时间,我开发了Sketchify, 该工具可以把任何以SVG为渲染技术的可视化转化为手绘风格.(参考手绘风格的数据可视化实现 ...

  9. 实战技术:利用深度学习实现手绘数据可视化的生成

    个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈 前一段时间,我开发了Sketchify, 该工具可以把任何以SVG为渲染技术的可视化转化为手绘风格.(参考手绘风格的数据可视化实现 ...

最新文章

  1. 客快物流大数据项目(十):Docker容器命令
  2. matlab绘制立体条形图
  3. Visual Studio 2017软件安装教程
  4. apache2.4配置虚拟主机
  5. python 读grid 数据_科学网—Python_机器学习_总结14:Grid search - 李军的博文
  6. 从操作系统层面描述线程的五种状态
  7. 如何使用Dockerfile构建镜像
  8. php 环境变量有什么用,什么是环境变量,Linux环境变量及作用
  9. 图形学之空间坐标变化之三维图形观察及变换
  10. Python学习笔记之While循环(一)
  11. 安装node.js、webpack、vue 和vue-cli 以及安装速度慢/不成功的解决方法
  12. 正则表达式大全(汇总)
  13. 大厂程序员手把手教你如何写简历(附简历模板)
  14. 在java中实现订餐系统_Java实现简单订餐系统
  15. 浙江大学计算机答辩模板,浙江大学 答辩通用模板
  16. Springboot 基于微信小程序的高校学生疫情在校封闭管理系统的设计与实现 毕业设计-附源码240904
  17. Java8 新特性并发篇(一) | 线程与执行器
  18. iOS开发 swift 3dTouch实现 附代码
  19. Java项目专栏之数据库建表
  20. centos8安装mysql8_CentOS 8安装MySQL8.0.22图文教程

热门文章

  1. 作为移动开发你不能不了解的编译流程
  2. 大一c语言考试题模板,大一计算机考试操作题
  3. 后台管理系统导出数据列表返回二进制数据,下载后为null
  4. 注册登录显示个人中心
  5. antDesign menu 自定义修改选中样式,一级和多级菜单
  6. 神经网络的核心——寻优Wi权重系数
  7. “拒绝了对对象数据库的 EXECUTE 权限”之解决
  8. Oracle GoldenGate概述
  9. String.valueOf() 方法的使用
  10. Activiti工作流(二)