这篇都是web前端技术,可能我还没有找到合适的方式,目前没有验证成功。
想法很简单,就是根据js的一些api,编辑arraybuffer之后保存图片,因为发现在原始的arraybuffer 后面添加数据,对图片显示没影响, 能够打乱图片并且在根据存储在图片中arraybuffer的数据规则,进行恢复。
进入正题前,需要对下面两点有所了解
- ArrayBuffer
- Int8Array (Int16Array) 等等
ArrayBuffer 不能直接操作需要转换成 Int8Array
const bf = new ArrayBuffer(10); const ar = new Int8Array(bf); //处理之后可以 //ar.buffer 获取 arraybuffer
var fileReader = new FileReader(); fileReader.onload = function(e) { fileContent = e.target.result; callback(fileContent); } fileReader.readAsArrayBuffer(file);
整体方法,获取图片的信息,根据信息设置成几行几列的小图片区域,打乱顺序。
- 根据图片的arraybuffer 获取 图片的尺寸, 如有更简单的方式可以告诉我。
function getImageSize(bf) { let blob = new Blob( [ bf ], { type: "image/png" } ); let urlCreator = window.URL || window.webkitURL; let imageUrl = urlCreator.createObjectURL( blob ); let img = new Image(); return new Promise(function(resolve){ img.onload = function(){ resolve({w:img.naturalWidth, h:img.naturalHeight}); }; img.src = imageUrl; }) }
- 根据图片的尺寸,获取裁份以及顺序的调整
//计算打乱顺序 function calculateRandomRule(imgsize){ let sw=0, sh=0; let x,y; //xy轴划分 let randomlist = [] for(let i=4; i<Math.max(imgsize.w,imgsize.h); i++) { if(imgsize.w%i == 0) { sw = imgsize.w/i; x = i; if(sh){break} } if(imgsize.h%i == 0) { sh = imgsize.h/i; y = i; if(sw){break} } }; for(let i=0; i<x*y; i++) { randomlist.push(i); } randomlist = randomlist.sort(() => 0.4 - Math.random()) return { sw, sh, x, y, randomlist } }
- 用canvas根据规则进行处理并显示成图片
function encodeImage(box) { // const cs = document.querySelector('canvas'); const cs = document.createElement('canvas'); const ctx = cs.getContext('2d'); const img = document.getElementById('photo'); cs.width = img.naturalWidth; cs.height = img.naturalHeight; let sw =box.sw, sh=box.sh, x = box.x, y=box.y; ctx.drawImage(img,0,0); let imgdataList = [], list=box.randomlist; for(let i=0; i<y; i++) { for(let j=0; j<x; j++) { imgdataList.push(ctx.getImageData(j*sw,i*sh,sw,sh)); } }; ctx.fillRect(0,0,cs.width,cs.height); for(let i=0, j=0; i<list.length; i++) { if(i >= x && (i%x) == 0) { j++; } ctx.putImageData(imgdataList[list[i]], sw*(i%x),sh*j); } cs.toBlob(function(blob){ var urlCreator = window.URL || window.webkitURL; var imageUrl = urlCreator.createObjectURL(blob); var img = document.querySelector("#photo2"); img.src= imageUrl },"image/png") }
- 来看下整体方法
async function callBack(m){ let imgsize = await getImageSize(m); let randomObj = calculateRandomRule(imgsize); let arr = new Int8Array(m); let boxabf = new ArrayBuffer(m.byteLength/50); let newarr = new Int8Array(arr.length+randomObj.randomlist.length+1); let boxarr = new Int8Array(boxabf.byteLength); for(let i =0; i<newarr.length; i++){ if(i>=arr.length){ if(i=== arr.length+randomObj.randomlist.length){ newarr[i] = randomObj.randomlist.length; } else{ newarr[i] = randomObj.randomlist[i-arr.length]; } } else { newarr[i] = arr[i] }; } encodeImage(randomObj); }
最后再总结一下
- 图片的arraybuffer增加字节长度,不修改原始的数据只添加,是不影响显示的,
- arraybuffer 减少是只能显示图片的一部分,但是尺寸不变