抛砖引玉,孢子,一种另类的WP7第三方应用数据交换方式
孢子,一种另类的WP7第三方应用数据交换方式
《孢子》这个游戏玩过的人应该对里面的模型很有印象,尤其会对里面只靠一张PNG就能在游戏中还原成3D很感兴趣,今天要介绍的就是这种技术:在PNG里隐藏我们需要的数据,利用Zune同步到WP7,然后使用MediaLibrary或者PhotoChooserTask读取后经过解析获取隐藏的数据,从而达到想WP7导入任何数据的目的!
因为其来源于孢子,所以我也将其命名为“孢子”!
首先,有兴趣的朋友先可以看看PNG格式规范,这里有一排你文章详细讲解了PNG数据格式:[url]http://wenku.baidu.com/view/c495bf4569eae009581bec99.html[/url]
我们要做的,就是向PNG写入一个自定义数据块!
这是目前我定义一套数据存储规范,如有不当或更好的方案我们一起来完善
写入数据的核心代码如下:
public void Write(string[] filenames) { this.start = this.SourceStream.Length - IEND.Length; // 提取结束标记 this.SourceStream.Position = this.start; this.SourceStream.Read(this.IEND, 0, this.IEND.Length); this.SourceStream.Position = this.start; // 生成数据块标记 Array.Copy(Encoding.ASCII.GetBytes("IMHD"), 0, this.IMHD, 8, 4); // 写入数据块起始标记 this.SourceStream.Write(this.IMHD, 0, this.IMHD.Length); this.length += this.IMHD.Length; // 写入数据内容 //byte[] h2 = Encoding.Unicode.GetBytes(BOUNDARY_HEADER); //this.SourceStream.Write(h2, 0, h2.Length); //this.length += h2.Length; foreach (var file in filenames) { if (File.Exists(file)) { var b1 = Encoding.Unicode.GetBytes(Path.GetFileName(file)); var b2 = BitConverter.GetBytes(b1.Length); // 写入文件名长度 this.SourceStream.Write(b2, 0, b2.Length); this.length += b2.Length; // 写入文件名 this.SourceStream.Write(b1, 0, b1.Length); this.length += b1.Length; using (var fs = new FileStream(file, FileMode.Open)) { var b3 = BitConverter.GetBytes(fs.Length); // 写入文件长度 this.SourceStream.Write(b3, 0, b3.Length); this.length += b3.Length; // 写入文件内容 var buffer = new byte[8192]; var count = 0; while (fs.Position < fs.Length) { count = fs.Read(buffer, 0, buffer.Length); this.SourceStream.Write(buffer, 0, count); } this.length += fs.Length; var b4 = BitConverter.GetBytes(CRC.CRC32(fs)); // 写入CRC校验 this.SourceStream.Write(b4, 0, b4.Length); this.length += b4.Length; } } } // 写入数据总长度 var lenBytes = BitConverter.GetBytes(this.length - 4); this.SourceStream.Position = this.start; this.SourceStream.Write(lenBytes, 0, lenBytes.Length); Debug.WriteLine("[w]length:" + (this.length - 4)); // 写入数据CRC var crc = CRC.CRC32(this.SourceStream, this.start, this.length); var crcBytes = BitConverter.GetBytes(crc); this.SourceStream.Position = this.start + this.length; this.SourceStream.Write(crcBytes, 0, crcBytes.Length); Debug.WriteLine("[w]crc:" + crc); // 回写结束标记 this.SourceStream.Write(this.IEND, 0, this.IEND.Length);
依赖此技术,WP7的数据同步障碍将不复存在,例如,我的书中圣,我可以将一本书打包进PNG,在阅读器里读出来;再比如,将一个rmvb文件打包进PNG,你可以开发个播放器,播放它!其他更多创意尽在你的想象!
本来想做个完整的Demo再放,但是看了下工作计划,貌似如果等完整Demo昨晚不知道猴年马月了,那就先放出来核心代码吧
包括了写入数据读取数据,测试用例是命令行项目,但放到WP7上也很简单,因为操作的都是流,只要你能获取图片流就能搞定,例如MediaLibrary,PhotoChooserTask等
希望这种技术能为大家带来帮助,另外本文提供的源代码,你可以随意修改,使用,但是如果你对其作了改进,希望能反馈给我一份,谢谢
源代码下载:https://files.cnblogs.com/zjfeiye/MoHooSpore.Demo.zip
最后说个事,有人宣称:
1)在图片中隐藏数据是他的专利,其他人要用这种方式必须提到是他发明的
2)在WP7中用PhotoChooserTask读取图片数据流是他的专利,其他人要用这种方式必须提到是他发明的
大家是否觉得可笑?本人在此不做任何评论,但本人也不声明此技术是本人原创,因为这种技术可以说早就被用烂了