侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

imagedata有效性实验

2024-05-08 星期三 / 0 评论 / 0 点赞 / 55 阅读 / 8166 字

引路蜂<a href="#0x1">0x1.术语概念</a><a href="#0x2">0x2.利用as3导出像素数据</a><a href="#0x3">0x3.html5读取导出的像素数据</a

引路蜂

  • <a href="#0x1">0x1.术语概念</a>
  • <a href="#0x2">0x2.利用as3导出像素数据</a>
  • <a href="#0x3">0x3.html5读取导出的像素数据</a>
  • <a href="#0x4">0x4.用画布显示像素数据</a>
  • <a href="#0x5">0x5.引申出来的想法</a>

<a name="0x1"><strong><b><em>0x1.</em>术语概念</b></strong></a>

位图:位图图像用图像的宽度和高度来定义,以像素为量度单位,每个像素包含的位数表示像素包含的颜色数。在使用 RGB 颜色模型的位图图像中,像素由三个字节组成:红、绿和蓝。每个字节包含一个 0 至 255 之间的值。

Alpha : 颜色或图像中的透明度级别(更准确地说是指不透明度)。Alpha 量通常称为Alpha 通道值。

ARGB: 颜色一种配色方案,其中每个像素的颜色都是红、绿和蓝色值的混合颜色,并且其透明度被指定为一个 Alpha 值。

AS3 : 是ActionScript3 , flash开发所需要的脚本语言。 基于ECMA规范。

BitmapData: actionscript3的一个api ,专门用来处理位图数据的。


<a name="0x2"><strong><b><em>0x2.</em>利用as3导出像素数据</b></strong></a>

首先创建一个AS3的项目, 名字随便写啦。工程创建好去网上搜两张图片作为测试用。

嵌入图片数据

	[Embed(source="assets/p2292415033.jpg")] public var bd1:Class;	[Embed(source="assets/p2299425320.jpg")] public var bd2:Class;

读取数据到内存

	  var bitmapData1:BitmapData = (new bd1() as Bitmap).bitmapData;  var bitmapData2:BitmapData = (new bd2() as Bitmap).bitmapData;			  var bytes:ByteArray = bitmapData1.getPixels(new Rectangle(0,				0,				bitmapData1.width,				bitmapData1.height));			  trace(bytes.length);///1068000

图片宽度和高度是 445x600 那么对应的字节数是1068000, 为什么是1068000而不是267000呢,因为这个字节数组返回的是RGBA的数据,四个byte组成一个像素,所以在所有像素的基础上在x4 就是1068000这个值了。

接下来需要导出位图的原始像素了。

//  setp2 导出位图var file:File = new File(File.applicationDirectory.    resolvePath("data/test.bin").nativePath);try {    var stream:FileStream = new FileStream();    stream.open(file, FileMode.WRITE);    stream.writeBytes(bytes);    stream.close();    trace("done");} catch (e:Error) {    trace(e);    stream.close();}

成功之后,我们可以看下工程下有没有这个data目录和文件。我们虽然成功导出了,但是现在还面临一个问题就是如何测试我们导出的数据是可以被html5所用呢? 继续吧。


<a name="0x3"><strong><b><em>0x3.</em>html5读取导出的像素数据</b></strong></a>

创建一个html5的工程,新建一个img的目录然后把我们生成的bin文件拷贝进去,继而开始撸代码吧。如果不知道怎么创建html5或者不知道什么是html5,请移步或者自行脑部去吧。创建一个空的画布,以备不时之需。

   var canvas = document.createElement("canvas");   canvas.setAttribute("id", "mycanvas");    canvas.setAttribute("width", 800);    canvas.setAttribute("height",600);  var body = document.getElementsByTagName("body")[0];    body.appendChild(canvas);

我们通过使用2代XMLHttpRequest可以很方便的我们产生的2进制文件读取进来。var request = new XMLHttpRequest();request.open('GET', 'img/test.bin', true);request.responseType = 'arraybuffer';

 request.onload = function(e) {    if (this.status == 200) {        console.log(this.response);    } } request.send();


<a name="0x4"><strong><b><em>0x4.</em>用画布显示像素数据</b></strong></a>

通过之前的操作我们已经完成了从0到1的质变, 我们的测试才刚刚开始呢,所以诸位大神准备脑洞大开,进行杀戮吧。

ps:这里不得不吐槽一句,canvas和arraybuff的api设计太不站在人类的发展角度考虑了。

我们现在的是一个不需要图像解码的过程(一般异步加载的Image对象会执行解码),以往异步解码和同步解码都会拖性能(我做过一个测试500张小图片直接使用拷贝像素和默认解码的效率相差60多倍)。

现在我们看看我们所需要API的原型

没错我们需要的就是他,我们的好朋友。我们可以通过画布的这两个API对图形进行批量设置像素,重要的是没有解码的过程哦。。

这是ImageData的原型

我们发现他的get_data就是byte数组,这样我们可以不加处理的就把数据给设置进去。不过设置之前我们要设置他的宽度和高度哦。这个我们的数据里没有,不过我下一篇里会有更好的方案,目前先写死445x600吧。

因为一切都是理论, 所以实现的时候有个小问题就是数据不对,图像完全错误了。

所以需要动态的调整过来。html5的顺序是rgba而as3的顺序是argb,我也是醉了。

另外直接给imgData.data赋值也是不起作用。

        var bytes = this.response;        var arr=new Uint8Array(bytes,0,1068000);                console.log(arr.length,arr[0],arr[1],arr[2],arr[3]);        var ctx   = canvas.getContext("2d");        var imgData=ctx.createImageData(445,600);//                  imgData.data=arr;        for (var i=0;i<imgData.data.length;i+=4)          {              imgData.data[i+0]=arr[i+1];//r = a              imgData.data[i+1]=arr[i+2];//g = r              imgData.data[i+2]=arr[i+3];//b = g              imgData.data[i+3]=arr[i+0];//a = b          }        console.log(imgData.data.length)        ctx.putImageData(imgData,0,0);        body.appendChild(canvas);

来张成功后的图。

<a name="0x5"><strong><b><em>0x5.</em>0x5.引申出来的想法</b></strong></a>

通过这次实验有几点不足。

1是生成的尺寸,比源文件大了10几倍, 因为没有用压缩算法,而以前用as3的时候直接可以使用ByteArray压缩体积会很小。html5还需要在研究一下,目前还不成熟。

2是读取图片的效率。如果是我当初理想化状态, imgData.data=arr;可以直接赋值,这无疑是效率的最优, 但是确是不能,也许我没有找对方法,有待优化。

3没有一种有效的组织形式,比如as3使用的类似技术的时候可以直接将n个byte数组和符号表等打包成一个2进制对象。直接系同级别的反序列化,不需要人工干预,目前无法大批量的生产。这点也需要优化。

好了。就写到这里吧。

广告 广告

评论区