Zipファイルのプレビューinfo.xmlつき

使いやすいように整理してみた。

↓これを読み込んでいる。
http://www.mztm.jp/wonderfl/zipfilewithxml.zip

クリエイティブコモンズの画像を使いたい場合、クレジットを入れないといけない。
画像だけをzip圧縮したものを使うと便利だけど、クレジットがわからなくなる。
ならば、クレジットをまとめたxmlを同梱するのはどうだろう、と思った。
xmlの書式で試行錯誤をするのは嫌なので、
とりあえず、LazyXMLLoaderの書式に準拠してみた。

Zipファイルのプレビュー3 – wonderfl build flash online

Zipファイルの中にBulkLoaderのLazyXMLLoaderの書式のxmlファイルが
あった場合、一緒に読み出せるようにした。
また、xmlと同じ順番で読み出せるように、ソートした。

たくさんの画像と、info.xmlでファイルを管理することを想定して、
画像だけのarray、imagesを作った。

contentは全部が入っているが、
その中から画像だけを抜き出して参照できるようにしたのが、images。

▼ActionScript AS3(FP10)

/*
 * 使いやすいように整理してみた。
 * 
 * ↓これを読み込んでいる。
 * http://www.mztm.jp/wonderfl/zipfilewithxml.zip
 * 
 * クリエイティブコモンズの画像を使いたい場合、クレジットを入れないといけない。
 * 画像だけをzip圧縮したものを使うと便利だけど、クレジットがわからなくなる。
 * ならば、クレジットをまとめたxmlを同梱するのはどうだろう、と思った。
 * xmlの書式で試行錯誤をするのは嫌なので、
 * とりあえず、LazyXMLLoaderの書式に準拠してみた。
 * 
 * =========================
 * 
 * Zipファイルの中にBulkLoaderのLazyXMLLoaderの書式のxmlファイルが
 * あった場合、一緒に読み出せるようにした。
 * また、xmlと同じ順番で読み出せるように、ソートした。
 * 
 * たくさんの画像と、info.xmlでファイルを管理することを想定して、
 * 画像だけのarray、imagesを作った。
 * 
 * contentは全部が入っているが、
 * その中から画像だけを抜き出して参照できるようにしたのが、images。
 * */

package {
    import flash.display.Sprite;
    import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFormat;
    import flash.display.Bitmap;

    public class Main extends Sprite {
        private var _zipLoader:ZipLoader;

        public function Main() {
            var urlStr:String = (this.loaderInfo.url);
            if (urlStr.substr(0, String("http://swf.wonderfl.net/").length) == "http://swf.wonderfl.net/") {
                //wonderfl用
                urlStr = "http://www.mztm.jp/wonderfl/";
            }else {
                //wordpressだとフルパスじゃないとダメみたいなので
                urlStr = urlStr.substr(0, urlStr.lastIndexOf("/")) + "/";
            }
            init(urlStr + "zipfilewithxml.zip");
        }

        private function init(url:String):void {
            _zipLoader = new ZipLoader();
            _zipLoader.add(url);
            _zipLoader.addEventListener(Event.COMPLETE, zipLoadComp);
            _zipLoader.start();
        }
        private function zipLoadComp(event:Event):void {
			//_zipLoader.contentsと
			//_zipLoader.imagesはxmlの記述順にソートしてある。
			
			//背景のテキスト
			var infoXMLtf:TextField = new TextField();
			infoXMLtf.defaultTextFormat = new TextFormat("_sans", 10);
			infoXMLtf.text = _zipLoader.infoXML;
			infoXMLtf.width = infoXMLtf.height = 465;
			this.addChild(infoXMLtf);
			//画像
			var n:int = _zipLoader.images.length;
			for (var i:int = 0; i < n; i++) {
				var content:Content = _zipLoader.images[i];
				var bitmap:Bitmap = content.getBitmap();
				bitmap.x = 60 + 60 * i;
				bitmap.y = 60 + 60 * i;
				
				//クレジット
				var tf:TextField = new TextField();
				tf.defaultTextFormat = new TextFormat("_sans", 10);
				tf.text = "by " + content.fileXML.info.by;
				tf.textColor = 0xFFFFFF;
				tf.autoSize = "left";
				tf.backgroundColor = 0x000000;
				tf.background = true;
				bitmap.bitmapData.draw(tf);
				
				this.addChild(bitmap);
			}
			
			
			//以下は上と同じ機能
			/*
            var n:int = _zipLoader.contents.length;
            for (var i:int = 0; i < n; i++) {
				var content:Content = _zipLoader.contents[i];
				if (_zipLoader.contents[i].type == "image") {
					var index:int = content.index;
					var bitmap:Bitmap = content.getBitmap();
					bitmap.x = 60 + 60 * index;
					bitmap.y = 60 + 60 * index;
					
					//クレジット
					var tf:TextField = new TextField();
					tf.defaultTextFormat = new TextFormat("_sans", 10);
					tf.text = "by " + content.fileXML.info.by;
					tf.textColor = 0xFFFFFF;
					tf.autoSize = "left";
					tf.backgroundColor = 0x000000;
					tf.background = true;
					bitmap.bitmapData.draw(tf);
					
					this.addChild(bitmap);
				}else if (content.type == "text") {
					var infoXMLtf:TextField = new TextField();
					infoXMLtf.defaultTextFormat = new TextFormat("_sans", 10);
					infoXMLtf.text = content.getXML();
					infoXMLtf.width = infoXMLtf.height = 465;
					this.addChild(infoXMLtf);
				}
            }
			*/
			
        }
    }
}


import flash.display.Bitmap;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import nochump.util.zip.*;
class ZipLoader {
    private var _listener:Function = function(event:Event):void { };
    private var _url:String;
    private var _imageLoaderCount:int;
    private var _imageLoadedCount:int;
    public var contents:Array;
	//画像だけ取り出しやすいようにimagesにも参照を張っている
	public var images:Array;
	//infoXMLだけも取り出しやすいように
	public var infoXML:XML;
	public var infoXMLName:String = "info.xml";
	private var zipFileName:String = "";
    public function ZipLoader() { };
    public function add(url:String):void {
        _url = url;
    }
    public function start():void {
        if (_url.length < 5) {
            return;
        }
        var loader_obj:URLLoader = new URLLoader();
        loader_obj.addEventListener(Event.COMPLETE, loadComp);
        loader_obj.dataFormat = "binary";
        loader_obj.load(new URLRequest(_url));
    }
    private function loadComp(event:Event):void {
        contents = [];
		images = [];
        _imageLoaderCount = 0;
        _imageLoadedCount = 0;
        var zipFile:ZipFile = new ZipFile(event.target.data);
        var n:int = zipFile.entries.length;
        for(var i:int = 0; i < n; i++) {
            var entry:ZipEntry = zipFile.entries[i];
            contents[i] = new Content(entry);
            contents[i].type = typeFormName(entry.name);
			
            switch (contents[i].type) {
                case "image":
                    contents[i].loader = new Loader();
                    contents[i].loader.loadBytes(zipFile.getInput(entry));
                    contents[i].loader.contentLoaderInfo.addEventListener(Event.COMPLETE, atComp);
					images.push(contents[i]);
                    _imageLoaderCount ++;
                    break;
                case "text":
                    contents[i].string = zipFile.getInput(entry).toString();
					//info.xmlファイルだった場合
					var directoryName:String = entry.toString();
					if(directoryName.length > infoXMLName.length){
						zipFileName = directoryName.substr(0, directoryName.lastIndexOf("/")) + "/";
					}
					directoryName = directoryName.substr(directoryName.lastIndexOf("/") + 1);
					if (directoryName == infoXMLName) {
						infoXML = contents[i].getXML();
						contents[i].index = -1;
					}
                    break;
                default:
            }
        }
    }
    private function atComp(event:Event):void {
        _imageLoadedCount ++;
        if (_imageLoadedCount == _imageLoaderCount) {
			setInfo();
            _listener(event);
        }
    }
	private function setInfo():void {
		if (infoXML) {
			var obj:Object = { };
			for (var i:int = 0; i < _imageLoadedCount; i++) {
				obj[contents[i].entry.toString()] = contents[i];
			}
			if (infoXML.files && infoXML.files.file) {
				var n:int = infoXML.files.file.length();
				for (i = 0; i < n; i++) {
					if (infoXML.files.file[i].url) {
						var url:String = infoXML.files.file[i].url.toString();
						if (obj[zipFileName + url]) {
							obj[zipFileName + url].fileXML =  infoXML.files.file[i];
							obj[zipFileName + url].index = i;
						}
					}
				}
				contents.sortOn("index", Array.NUMERIC);
				images.sortOn("index", Array.NUMERIC);
			}
		}
	}

    private var EXTENSIONS:Object = {
        //"swf":["swf"], "movie":["mp4", "flv"],未対応
        "image":["jpg", "jpeg", "gif", "png"],
        "text":["txt", "js", "xml", "php", "asp", "as", "html", "htm", "php", "py", "mxml"]
        };
    private function typeFormName(name:String):String {
        var str:String = name.substr(name.lastIndexOf(".") + 1).toLowerCase();
        var extension:String;
        for (var p:String in EXTENSIONS) {
            var n:int = EXTENSIONS[p].length;
            for (var i:int = 0; i < n; i++) {
                extension = EXTENSIONS[p][i];
                if(extension == str){
                    str = p;
                    break;
                }
            }
        }
        return str;
    }

    public function addEventListener(type:String,listener:Function):void{
        _listener = listener;
    }
}
class Content {
    public var entry:ZipEntry;
    public var type:String;
    public var loader:Loader;
    public var string:String;
	public var fileXML:XML;
	public var index:int;
    public function Content(entry:ZipEntry):void {
        this.entry = entry;
    }
    public function getBitmap():Bitmap {
        return Bitmap(loader.contentLoaderInfo.content);
    }
    public function getText():String {
        return string;
    }
	public function getXML():XML {
		return new XML(string);
	}
}

info.xml

<?xml version="1.0" encoding="utf-8" ?>
<data>

	<files>
		<file>
			<id>img0</id>
			<type>image</type>
			<url>3384297473_7a5f8e7933_t.jpg</url>
			<info>
				<by>epSos.de</by>
			</info>
		</file>
		<file>
			<id>img1</id>
			<type>image</type>
			<url>2851026377_f602b4ea14_t.jpg</url>
			<info>
				<by>Olof S</by>
			</info>
		</file>
		<file>
			<id>img2</id>
			<type>image</type>
			<url>3705966286_3c08e6a540_t.jpg</url>
			<info>
				<by>Furryscaly</by>
			</info>
		</file>
		<file>
			<id>img3</id>
			<type>image</type>
			<url>361442413_383a41eb63_t.jpg</url>
			<info>
				<by>aussiegall</by>
			</info>
		</file>
		<file>
			<id>img4</id>
			<type>image</type>
			<url>319451095_0c56f57e69_t.jpg</url>
			<info>
				<by>Capitan Giona</by>
			</info>
		</file>
	</files>

</data>