十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
这篇文章主要介绍“html5中怎么通过png图的rgba值缓存数据”,在日常操作中,相信很多人在html5中怎么通过png图的rgba值缓存数据问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”html5中怎么通过png图的rgba值缓存数据”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
成都创新互联公司是少有的网站建设、网站设计、营销型企业网站、小程序开发、手机APP,开发、制作、设计、买友情链接、推广优化一站式服务网络公司,从2013年成立,坚持透明化,价格低,无套路经营理念。让网页惊喜每一位访客多年来深受用户好评
原理
我们知道,通过为静态资源设置Cache-Control和Expires响应头,可以迫使浏览器对其进行缓存。浏览器在向后台发起请求的时候,会先在自身的缓存里面找,如果缓存里面没有,才会继续向服务器请求这个静态资源。利用这一点,我们可以把一些需要被缓存的信息通过这个静态资源缓存机制来进行储存。
那么我们如何把信息写入到静态资源中呢?canvas提供了.getImageData()方法和.createImageData()方法,可以分别用于读取和设置图片的rgba值。所以我们可以利用这两个API进行信息的读写操作。
接下来看原理图:
当静态资源进入缓存,以后的任何对于该图片的请求都会先查找本地缓存,也就是说信息其实已经以图片的形式被缓存到本地了。
注意,由于rgba值只能是[0, 255]之间的整数,所以本文所讨论的方法仅适用于纯数字组成的数据。
静态服务器
我们使用node搭建一个简单的静态服务器:
const fs = require('fs') const http = require('http') const url = require('url') const querystring = require('querystring') const util = require('util') const server = http.createServer((req, res) => { let pathname = url.parse(req.url).pathname let realPath = 'assets' + pathname console.log(realPath) if (realPath !== 'assets/upload') { fs.readFile(realPath, "binary", function(err, file) { if (err) { res.writeHead(500, {'Content-Type': 'text/plain'}) res.end(err) } else { res.writeHead(200, { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'image/png', 'ETag': "666666", 'Cache-Control': 'public, max-age=31536000', 'Expires': 'Mon, 07 Sep 2026 09:32:27 GMT' }) res.write(file, "binary") res.end() } }) } else { let post = '' req.on('data', (chunk) => { post += chunk }) req.on('end', () => { post = querystring.parse(post) console.log(post.imgData) res.writeHead(200, { 'Access-Control-Allow-Origin': '*' }) let base64Data = post.imgData.replace(/^data:image\/\w+;base64,/, "") let dataBuffer = new Buffer(base64Data, 'base64') fs.writeFile('assets/out.png', dataBuffer, (err) => { if (err) { res.write(err) res.end() } res.write('OK') res.end() }) }) } }) server.listen(80) console.log('Listening on port: 80')
这个静态资源的功能很简单,它提供了两个功能:通过客户端传来的base64生成图片并保存到服务器;设置图片的缓存时间并发送到客户端。
关键部分是设置响应头:
res.writeHead(200, { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'image/png', 'ETag': "666666", 'Cache-Control': 'public, max-age=31536000', 'Expires': 'Mon, 07 Sep 2026 09:32:27 GMT' })
我们为这张图片设置了一年的Content-Type和十年的Expires,理论上足够长了。下面我们来进行客户端的coding。
客户端
假设我们需要存储的是32位的数据,所以我们为canvas设置宽度为8,高度为1。到底为什么32位数据对应长度为8,是因为每一个像素都有一个rgba,对应着red,green,blue和alpha4个数值,所以需要除以4。
let keyString = '01234567890123456789012345678901' let canvas = document.querySelector('#canvas') let ctx = canvas.getContext('2d') let imgData = ctx.createImageData(8, 1) for (let i = 0; i < imgData.data.length; i += 4) { imgData.data[i + 0] = parseInt(keyString[i]) + 50 imgData.data[i + 1] = parseInt(keyString[i + 1]) + 100 imgData.data[i + 2] = parseInt(keyString[i + 2]) + 150 imgData.data[i + 3] = parseInt(keyString[i + 3]) + 200 } ctx.putImageData(imgData, 0, 0)
首先我们假设需要被缓存的字符串为32位的01234567890123456789012345678901,然后我们使用.createImageData(8, 1)生成一个空白的imgData对象。接下来,我们对这个空对象进行赋值。为了实验效果更加直观,我们对rgba值都进行了放大。设置完了imgData以后,通过.putImageData()方法把它放入我们的canvas即可。
我们现在可以打印一下,看看这个imgData是什么:
// console.log(imgData.data) [50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201, 52, 103, 154, 205, 56, 107, 158, 209, 50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201]
接下来,我们要把这个canvas编译为一张图片的base64并发送给服务器,同时接收服务器的响应,对图片进行缓存:
$.post('http://xx.xx.xx.xx:80/upload', { imgData: canvas.toDataURL() }, (data) => { if (data === 'OK') { let img = new Image() img.crossOrigin = "anonymous" img.src = 'http://xx.xx.xx.xx:80/out.png' img.onload = () => { console.log('完成图片请求与缓存') ctx.drawImage(img, 0, 0) console.log(ctx.getImageData(0, 0, 8, 1).data) } } })
代码很简单,通过.toDataURL()方法把base64发送到服务器,服务器处理后生成图片并返回,其图片资源地址为http://xx.xx.xx.xx:80/out.png。在img.onload后,其实图片就已经完成了本地缓存了,我们在这个事件当中把图片信息打印出来,作为和源数据的对比。
结果分析
开启服务器,运行客户端,***次加载的时候通过控制台可以看到响应的图片信息:
200 OK,证明是从服务端获取的图片。
关闭当前页面,重新载入:
200 OK (from cache),证明是从本地缓存读取的图片。
接下来直接看rgba值的对比:
源数据: [50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201, 52, 103, 154, 205, 56, 107, 158, 209, 50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201] 缓存数据:[50, 100, 152, 245, 54, 105, 157, 246, 57, 109, 149, 244, 52, 103, 154, 245, 56, 107, 157, 247, 50, 100, 152, 245, 54, 105, 157, 246, 57, 109, 149, 244]
之前得到的结论,源数据与缓存数据存在误差的原因,经查证后确定为alpha值的干扰所致。如果我们把alpha值直接定为255,并且只把数据存放在rgb值内部,即可消除误差。下面是改良后的结果:
源数据: [0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255, 2, 3, 4, 255, 6, 7, 8, 255, 0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255] 缓存数据:[0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255, 2, 3, 4, 255, 6, 7, 8, 255, 0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255]
到此,关于“html5中怎么通过png图的rgba值缓存数据”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!