<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>FACEs</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/" />
    <link rel="self" type="application/atom+xml" href="http://faces.jp/atom.xml" />
   <id>tag:faces.jp,2011://1</id>
    <link rel="service.post" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1" title="FACEs" />
    <updated>2011-09-04T02:13:48Z</updated>
    <subtitle>A NEW POSITION OF WEB CREATION</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type  3.33-ja</generator>
 
<entry>
    <title>PsdReader.js</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2011/09/psdreaderjs.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=675" title="PsdReader.js" />
    <id>tag:faces.jp,2011://1.675</id>
    
    <published>2011-09-04T01:21:16Z</published>
    <updated>2011-09-04T02:13:48Z</updated>
    
    <summary>PSDから画像を取得。Chrome、FireFoxのみ。...</summary>
    <author>
        <name>ao</name>
        
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        PSDから画像を取得。Chrome、FireFoxのみ。
        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
-->
</style>

<div class="ao">

<p>FileReader メモ<br />
・Safari とスマホに FileReader がない。 File API も最小限。<br />
・FireFox は File API に lastModifiedDate がない。
</p>


<pre>
//こんな感じで使う。

var reader		= new FileReader(file);
var uploader	= new FileUploader();
var psd;
reader.onload	= function(e){
	psd 		= new PsdReader(e.target.result);
	var base64	= psd.getDataURL().split(',').pop()
	uploader.upload(base64);
}
reader.readAsBinaryString(file);

</pre></div>

<p>PsdReader</p>
<div class="ao"><pre>
function PsdReader(file){this.initialize.apply(this, arguments);}
PsdReader.prototype = {
	//classPhpPsdReader.php
	//http://www.phpclasses.org/browse/file/17603.html
	initialize:function(str){
		var s = this.data = new BinaryStream(str);
		this.info	= {};
		if(this.data.read(4)=='8BPS'){
			$log('psd');
			//Photoshop　PSD 解析例
			//http://hp.vector.co.jp/authors/VA032610/operation/sample/PSD.htm
			this.info.versionId 		= this.data.getUShort();
			this.data.seek(6,'SEEK_CUR');
			this.info.channels			= this.data.getUShort();
			this.info.height			= this.data.getULong();
			this.info.width				= this.data.getULong();
			this.info.colorDepth		= this.data.getUShort();//色深度
			this.info.colorMode			= this.data.getUShort();//カラーモード
			this.info.colorModeData		= this.data.getSection(false);
			this.info.imageResources	= this.data.getSection(false);
			this.info.layerMaskData		= this.data.getSection(false);
			this.info.compressionType	= this.data.getUShort();
			this.info.oneColorChannelPixelBytes	= this.info.colorDepth/8;
			this.colorBytesLength		= this.info.height*this.info.width*this.info.oneColorChannelPixelBytes;
			
			if (this.info.colorMode==2) {
				this.info.error = 'images with indexed colours are not supported yet';
				return false;
			}
			$log(this.info);
		}else{
			this.info.error = 'invalid or unsupported psd';
			return false;
		}
	},
	
	getDataURL:function(){
		if(!this.hasOwnProperty('canvas')) this.draw();
		return this.canvas.toDataURL();
	},
	
	getImageData:function(){
		if(!this.hasOwnProperty('imageData')) this.draw();
		return this.imageData;
	},
	
	draw:function(){
		switch(this.info.compressionType) {
			case 1	: var s = this.unpackData();break;
			default	: var s = this.data;
		}
		this.canvas			= document.createElement('canvas');
		this.canvas.width	= this.info.width;
		this.canvas.height	= this.info.height;
		this.context		= this.canvas.getContext('2d');
		this.imageData		= this.context.getImageData(0,0,this.info.width,this.info.height); 
		//$('#Container').append(this.canvas);
		stopwatch.push(new Date());
		this.setImageDataByRGB8(s);
		this.context.putImageData(this.imageData,0,0);
	},
	
	setImageDataByRGB8:function(obj){
		var length = this.info.width*this.info.height;
        for(var channel	=0;channel&lt;3;channel++){
        	var index	= channel;
        	var start	= obj.pointer + this.colorBytesLength*channel;
        	var end		= start + length;
			for(var p=start;p&lt;end;p++){
				this.imageData.data[index] = obj.data.charCodeAt(p);
				index += 4;
			}
		}
		index = 3;
		for(var p=0;p&lt;length;p++){
			this.imageData.data[index] = 0xff;
			index += 4;
		}
	},
	
	unpackData:function(){
		this.info.scanLinesByteCounts = [];
		for (var i=0; i&lt;this.info.height*this.info.channels; i++){ 
			this.info.scanLinesByteCounts.push(this.data.getUShort());
		}
		var s = '';
		for (var i=0; i&lt;this.info.scanLinesByteCounts.length; i++) {
			s += this.getPackedBitsDecoded(this.data.read(this.info.scanLinesByteCounts[i]));
		}
		stopwatch.push(new Date());
		return new BinaryStream(s);
	},
	
	getPackedBitsDecoded:function(s){
		var p = 0;
		var returnString = '';
		while (1) {
			if (p&lt;s.length){
				var c = s.charCodeAt(p)
				var headerByteValue = this.toSignedChar(c);
			}else{
				return returnString;
			}
			p++;
			if (headerByteValue &gt;= 0) {
				for (i=0; i &lt;= headerByteValue; i++) {
					returnString += s.charAt(p);
					p++;
				}
			} else {
				if (headerByteValue != -128) {
					var copyByte = s.charAt(p);
					p++;
					for (i=0; i &lt; (1-headerByteValue); i++) {
						returnString += copyByte;
					}
				}
			}
		}
	},
	toSignedChar:function(c){
		c = c & 0xff;
		if (c&lt;128) return c;
		else return c-256;
	}
}
</pre></div>
<p>BinaryStream</p>
<div class="ao"><pre>
function BinaryStream(){this.initialize.apply(this, arguments);}
BinaryStream.prototype = {
	initialize:function(string){
		this.data = string;
		this.pointer = 0;
	},
	getULong:function(){
		var s = this.read(4);
		return (((((s.charCodeAt(0)&lt;&lt;8) + s.charCodeAt(1))&lt;&lt;8) + s.charCodeAt(2))&lt;&lt;8) +s.charCodeAt(3);
	},
	getUShort:function(){
		var s = this.read(2);
		return (s.charCodeAt(0) &lt;&lt; 8) + s.charCodeAt(1);
	},
	getUChar:function(){
		var s = this.read(1);
		return s.charCodeAt(0);
	},
	getSection:function(isReturn){
		var sectionLength = this.getULong();
		if(isReturn===false){
			this.seek(sectionLength,'SEEK_CUR');
			return null;
		}else{
			return this.read(sectionLength);
		}
	},
	read:function(bytes){
		var p = this.pointer + bytes;
		var s = this.data.slice(this.pointer,p);
		this.pointer = p;
		return s;
	},
	_getInteger:function(byteCount) {
		switch (byteCount) {
			case 4	:return this.getULong();break;
			case 2	:return this.getUShort();break;
			default	:return this.getUChar();
				//return hexdec($this-&gt;_hexReverse(bin2hex(fread($this-&gt;fp,$byteCount))));
		}
	},
	tell:function()		{return this.pointer;},
	seek:function(offset,whence){
		switch(whence){
			case 'SEEK_CUR'	:this.pointer += offset;break;
			default			:this.pointer  = offset;
		}
	}
}
</pre></div>]]>
    </content>
</entry>
<entry>
    <title>CSS3のアニメーションプロパティを動的生成するJavaScript</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2011/04/css3javascript.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=674" title="CSS3のアニメーションプロパティを動的生成するJavaScript" />
    <id>tag:faces.jp,2011://1.674</id>
    
    <published>2011-04-25T11:08:44Z</published>
    <updated>2011-04-25T12:42:55Z</updated>
    
    <summary>CSSのアニメーションプロパティでキーフレーム指定が面倒なので、動的に指定するJ...</summary>
    <author>
        <name>maegawa</name>
        <uri>/2006/07/post_2.html</uri>
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        <![CDATA[CSSのアニメーションプロパティでキーフレーム指定が面倒なので、動的に指定するJSを用意しました。<br>
動作確認環境は、Chrome、Safari、MobileSafariです。]]>
        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
div#demo1 {
	width :50px;
	height:50px;
	border:1px solid #000000;
	background-color: rgb(255,0,0);
}
div#demo1:hover {
	-webkit-animation:anime-name 2s linear;
}
@-webkit-keyframes anime-name {
	0%   { background-color: rgb(255,0,0); }
	100% { background-color: rgb(0,255,0); }
}
div#demo2 {
	width :50px;
	height:50px;
	border:1px solid #000000;
	background-color: rgb(255,0,0);
}
-->
</style>

<div class="ao">

<br>
<br>

<p>
<b>直接記述して指定する場合</b><br>
マウスオーバーすることで、赤色から緑色に変わります。<br>
直書きなので動的に色を変更（キーフレーム指定）するようなアニメーションは出来ません。
</p>

<div id="demo1"></div>

<pre>
&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;meta charset="utf-8" /&gt;
&lt;title&gt;demo-1&lt;/title&gt;
&lt;style&gt;
div#demo1 {
	width :50px;
	height:50px;
	border:1px solid #000000;
	background-color: rgb(255,0,0);
}
div#demo1:hover {
	-webkit-animation:anime-name 2s linear;
}
@-webkit-keyframes anime-name {
	0%   { background-color: rgb(255,0,0); }
	100% { background-color: rgb(0,255,0); }
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="demo1"&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>

<br>
<br>

<p>
<b>動的にJSから生成する場合</b><br>
直描きするコードと同様に色を変更するサンプルです。<br>
折角なので色の指定をランダムに指定します。
</p>

<script src="http://faces.jp/kazuhisa/jquery-1.5.2.min.js"></script>
<script src="http://faces.jp/kazuhisa/dynamic-css.js"></script>
<script>
$( function(){
	//初期化
	DynamicCSS.initialize();
	//CSSアニメーションルールを追加
	DynamicCSS.appendKeyframes( "anime-name", {
		"0%"  :{ "background-color": "rgb(255,0,0)" },
		"100%":{ "background-color": _rgb() }
	} );
	//CSSClassを追加
	DynamicCSS.appendRule( ".anime-class", {
	   "-webkit-animation":"anime-name 1s ease-out"
	} );
	var $demo2 = $( "#demo2" );
	    $demo2.bind( "mouseover", function( event ){
	        $demo2.addClass( "anime-class" );
	    } )
	    .bind( "webkitAnimationEnd", function(){
		    $demo2.removeClass( "anime-class" );
		} );
} );
function _rgb(){
	var r = Math.floor( Math.random()*255 );
	var g = Math.floor( Math.random()*255 );
	var b = Math.floor( Math.random()*255 );
	return "rgb("+r+","+g+","+b+");";
}
</script>
<div id="demo2"></div>

<pre>
&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;meta charset="utf-8" /&gt;
&lt;title&gt;demo-2&lt;/title&gt;
&lt;style&gt;
div#demo2 {
	width :50px;
	height:50px;
	border:1px solid #000000;
	background-color: rgb(255,0,0);
}
&lt;/style&gt;
&lt;script src="jquery-1.5.2.min.js"&gt;&lt;/script&gt;
&lt;script src="dynamic-css.js"&gt;&lt;/script&gt;
&lt;script&gt;
$( function(){
	//初期化
	DynamicCSS.initialize();
	//CSSアニメーションルールを追加
	DynamicCSS.appendKeyframes( "anime-name", {
		"0%"  :{ "background-color": "rgb(255,0,0)" },
		"100%":{ "background-color": _rgb() }
	} );
	//CSSClassを追加
	DynamicCSS.appendRule( ".anime-class", {
	   "-webkit-animation":"anime-name 1s ease-out"
	} );
	var $demo2 = $( "#demo2" );
	    $demo2.bind( "mouseover", function( event ){
	        $demo2.addClass( "anime-class" );
	    } )
	    .bind( "webkitAnimationEnd", function(){
		    $demo2.removeClass( "anime-class" );
		} );
} );
function _rgb(){
	var r = Math.floor( Math.random()*255 );
	var g = Math.floor( Math.random()*255 );
	var b = Math.floor( Math.random()*255 );
	return "rgb("+r+","+g+","+b+");";
}
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="demo2"&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>

<br>

<p>
位置、大きさ、角度を動的に変更したい場合のキーフレームの指定方法は次のようにできます。

<pre>
DynamicCSS.appendKeyframes( "anime-name", {
	"0%"  :{"-webkit-transform":"translate(0px,0px) rotate(0deg) scale(1.0);"},
	"100%":{"-webkit-transform":"translate(100px,200px) rotate(300deg) scale(2.0);"}
} );
</pre>

もしくは、

<pre>
DynamicCSS.appendKeyframes( "anime-name", {
	"0%"  :DynamicCSS.transform(0,0,0,1.0),
	"100%":DynamicCSS.transform(100,200,300,2.0)
} );
</pre>

という指定でも動きます。
</p>

<br>
<br>

<a href="http://faces.jp/kazuhisa/dynamic-css-demo.zip">サンプルファイルをダウンロード</a>

<br>
<br>
<br>
<br>

<div>]]>
    </content>
</entry>
<entry>
    <title>ほぼ HTML5 だけでサムネイル作成</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2011/03/_html5.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=673" title="ほぼ HTML5 だけでサムネイル作成" />
    <id>tag:faces.jp,2011://1.673</id>
    
    <published>2011-03-03T05:09:39Z</published>
    <updated>2011-03-03T05:54:12Z</updated>
    
    <summary>Flashでも同じようなことはできますが、HTML5だとiPhoneやiPadで...</summary>
    <author>
        <name>ao</name>
        
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        <![CDATA[Flashでも同じようなことはできますが、HTML5だとiPhoneやiPadでも動作したり、<br />
flv以外の動画もキャプったりできるはず。<br />
PNG作成→BASE64で送信までがHTML、受信して保存のみPHPという感じ。]]>
        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
-->
</style>
<div class="ao">
<p><br />html, js</p>
<pre>
// required
// jquery-1.5.1.min.js
// jquery.json-2.2.min.js

var Application = {
	post:function(action,data,callback){
		$.post('api.php?api='+action,data,callback);	
	},
	saveImage:function(f,d,c	){
		this.post('saveImage',$.toJSON({'filename':f,'data':d}),c);
	}
};

function isSafari(){
	if(navigator.userAgent.match(/Chrome/i))	return false;
	if(navigator.userAgent.match(/Safari/i))	return true;
	return false;
}

$(document).ready(main);

function main(){
	
	var img		= new Image();
	img.src		= '0107/Library204.png';
	img.onload	= function() {
		
		var thumbHeight	= 100; 
		var thumbWidth	= Math.round(img.width*thumbHeight/img.height);
		
		var thumb		= document.createElement('canvas');
		thumb.id		= 'canvas0';
		thumb.width		= thumbWidth;
		thumb.height	= thumbHeight;
		document.body.appendChild(thumb);
		
		if(isSafari()){
			//Safariは勝手にキレイに縮小される
			var buffer = img;
		}else{
			//それ以外のブラウザは一手間
			buffer			= document.createElement('canvas');
			buffer.id		= 'canvas2';
			buffer.width	= thumbWidth*2;
			buffer.height	= thumbHeight*2;
			buffer.getContext('2d').drawImage(img,0,0,buffer.width,buffer.height);
		}
		thumb.getContext('2d').drawImage(buffer, 0, 0,thumbWidth,thumbHeight);
		
		var s = thumb.toDataURL().split(',').pop();
		Application.saveImage('img/test.png',s,function(data){
			console.log(data)
		});
 	}
}

</pre>
<p>api.php</p>
<pre>
&lt;?php

$start = microTime(true)*1000;

switch($_GET['api']){
	case 'saveImage':saveImage();break;
}

function response($item){
	echo json_encode(array(
		'cost'		=> microTime(true)*1000-$GLOBALS['start'],
		'content'	=> $item
	));
}

function saveImage(){
	$data = json_decode(file_get_contents('php://input'));
	if(file_put_contents($data->filename,base64_decode($data->data))===false){
		response(false);
	}else{
		response(true);
	}
}

</pre></div>]]>
    </content>
</entry>
<entry>
    <title>js | CSSをスッキリ読みやすく</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2010/08/js_css.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=672" title="js | CSSをスッキリ読みやすく" />
    <id>tag:faces.jp,2010://1.672</id>
    
    <published>2010-08-14T06:56:34Z</published>
    <updated>2010-08-14T07:55:53Z</updated>
    
    <summary>PCだけでも手間がかかり、スマートフォンでも見れるようにとか考えていると、ハック...</summary>
    <author>
        <name>ao</name>
        
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        PCだけでも手間がかかり、スマートフォンでも見れるようにとか考えていると、ハック混ざりで使うCSSは本当に再利用しづらい。スタイルシートの可読性を上げるためにこういうのはどうでしょうか
        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
-->
</style>
<div class="ao">
<p>
iPhone → &lt;body id="Body" class="Webkit iPhone"&gt;&lt;/body&gt;<br />
Android → &lt;body id="Body" class="Webkit Android"&gt;&lt;/body&gt;<br />
IE8 → &lt;body id="Body" class="IE IE8"&gt;&lt;/body&gt;<br />
IE6 → &lt;body id="Body" class="IE ClassicIE IE6"&gt;&lt;/body&gt;<br />
FireFox → &lt;body id="Body" class="Gecko"&gt;&lt;/body&gt;<br />
<br />
上記みたいに HTML のボディ要素に js でスタイルを追加してると css がスッキリ。<br />

</p>
<pre>
.nodeStyle {
	/*IE8含むモダンブラウザ向け*/
}
.Webkit .nodeStyle {
	/*スマートフォン向けに拡張、CSS3*/
}
.Android .nodeStyle {
	/*Android 向けにゴニョゴニョ*/
}
.ClassicIE .nodeStyle {
	/*IE5,6,7 下位調整*/
}

</pre>
<p>コピペソース</p>
<pre>
// 要 prototype.js
var browser = [];
if(Prototype.Browser.IE){
	browser.push("IE");
	
	//http://msdn.microsoft.com/ja-jp/library/cc288325(VS.85).aspx
	if(document.documentMode){//IE8
		if(document.documentMode&lt;8) browser.push('ClassicIE');
		browser.push('IE'+document.documentMode);
	}else{
		browser.push('ClassicIE');
		if (document.compatMode){//IE&gt;=6
			if (document.compatMode == "CSS1Compat"){
				browser.push('IE7');
			}else{
				browser.push('IE6');
			}
		}else{
			browser.push('IE5');
		}
	}
}else if(Prototype.Browser.WebKit){
	browser.push('WebKit');
	if(navigator.userAgent.search(/iPhone/) != -1 )		browser.push('iPhone');
	if(navigator.userAgent.search(/iPad/) != -1 )		browser.push('iPad');
	if(navigator.userAgent.search(/iPod/) != -1 )		browser.push('iPod');
	if(navigator.userAgent.search(/Android/) != -1 )	browser.push('Android');
}else if(Prototype.Browser.Gecko){
	browser.push('Gecko');
}
if(browser.length&gt;0) $('Body').className = browser.join(' ');

</pre></div>]]>
    </content>
</entry>
<entry>
    <title>php | サムネイル処理コピペ</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2010/07/php_thumbnail.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=671" title="php | サムネイル処理コピペ" />
    <id>tag:faces.jp,2010://1.671</id>
    
    <published>2010-07-28T17:24:51Z</published>
    <updated>2010-07-28T17:48:55Z</updated>
    
    <summary>些細なくせに汎用化しようとすると大げさ、でも使用頻度は高い処理です。 バッチする...</summary>
    <author>
        <name>ao</name>
        
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        些細なくせに汎用化しようとすると大げさ、でも使用頻度は高い処理です。
バッチするときにクラスは使いにくいのでコピペ用の function で。
        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
-->
</style>
<div class="ao"><pre>
&lt;?php

//ini_set('memory_limit', '128M');
//set_time_limit(0);

$items = array();
forEach(glob('Images/*.jpg') as $file){
	$item	= array($file,fileMTime($file));
	$key	= sha1(implode('&',$item));
	thumbByHeight(	$file,"thumbCache/$key.height.jpg");
	thumbByWidth(	$file,"thumbCache/$key.width.jpg");
	thumbInside(	$file,"thumbCache/$key.inside.jpg");
	$items[] = $item;
}

//print_r($items);

function thumbByHeight($sourceFile,$thumbFile,$thumbHeight = 100){
	if(!file_exists($sourceFile)) return false;
	if(!file_exists($thumbFile)){
		$src			= imageCreateFromString(file_get_contents($sourceFile));
		$srcWidth		= imageSX($src);
		$srcHeight		= imageSY($src);
		$scale			= $thumbHeight/$srcHeight;
		$thumbWidth		= round($srcWidth*$scale);
		$thumb			= imageCreateTruecolor ( $thumbWidth , $thumbHeight );
		imageCopyResampled(
			$thumb,						$src,
			0,0,						0,0,
			$thumbWidth,$thumbHeight,	$srcWidth,$srcHeight
		);
		imagejpeg ($thumb,$thumbFile,100);
		touch($thumbFile,fileMTime($sourceFile));
	}
	return $thumbFile;
}

function thumbByWidth($sourceFile,$thumbFile,$thumbWidth = 100){
	if(!file_exists($sourceFile)) return false;
	if(!file_exists($thumbFile)){
		$src			= imageCreateFromString(file_get_contents($sourceFile));
		$srcWidth		= imageSX($src);
		$srcHeight		= imageSY($src);
		$scale			= $thumbWidth/$srcWidth;
		$thumbHeight	= round($srcHeight*$scale);
		$thumb			= imageCreateTruecolor ( $thumbWidth , $thumbHeight );
		imageCopyResampled(
			$thumb,						$src,
			0,0,						0,0,
			$thumbWidth,$thumbHeight,	$srcWidth,$srcHeight
		);
		imagejpeg($thumb,$thumbFile,100);
		touch($thumbFile,fileMTime($sourceFile));
	}
	return $thumbFile;
}

function thumbInside($sourceFile,$thumbFile,$thumbSize = 100){
	if(!file_exists($sourceFile)) return false;
	if(!file_exists($thumbFile)){
		$src			= imageCreateFromString(file_get_contents($sourceFile));
		$srcWidth		= imageSX($src);
		$srcHeight		= imageSY($src);
		if($srcWidth&gt;$srcHeight){
			$thumbWidth		= $thumbSize;
			$scale			= $thumbWidth/$srcWidth;
			$thumbHeight	= round($srcHeight*$scale);
		}else{
			$thumbHeight	= $thumbSize;
			$scale			= $thumbHeight/$srcHeight;
			$thumbWidth		= round($srcWidth*$scale);
		}
		$thumb			= imageCreateTruecolor ( $thumbWidth , $thumbHeight );
		imageCopyResampled(
			$thumb,						$src,
			0,0,						0,0,
			$thumbWidth,$thumbHeight,	$srcWidth,$srcHeight
		);
		imagejpeg($thumb,$thumbFile,100);
		touch($thumbFile,fileMTime($sourceFile));
	}
	return $thumbFile;
}

</pre></div>]]>
    </content>
</entry>
<entry>
    <title>php | parseGoogleSpreadsheets</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2010/06/php_parsegooglespreadsheetsast.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=670" title="php | parseGoogleSpreadsheets" />
    <id>tag:faces.jp,2010://1.670</id>
    
    <published>2010-06-16T05:26:37Z</published>
    <updated>2010-06-16T05:33:46Z</updated>
    
    <summary>クラウドというか、簡単なコンフィグの共有にGoogleのエクセルを使う。...</summary>
    <author>
        <name>ao</name>
        
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        クラウドというか、簡単なコンフィグの共有にGoogleのエクセルを使う。
        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
-->
</style>
<div class="ao"><pre>
$items = parseGoogleSpreadsheets('キー文字列');
print_r($items);

function parseGoogleSpreadsheets($key){
	$txt		= file_get_contents("http://spreadsheets.google.com/pub?key=$key&output=txt");
	$rows		= explode("\n",$txt);
	$headers	= explode("\t",trim(array_shift($rows)));
	$items		= array();
	forEach($rows as $row){
		$cells	= explode("\t",trim($row));
		$item = array();
		forEach($cells as $i => $cell){
			$item[$headers[$i]] = $cell;
		}
		$items[] = $item;
	}
	return $items;
}
</pre></div>]]>
    </content>
</entry>
<entry>
    <title>マルチタッチのマルチデバイスでマルチユーザー</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2010/06/iphone_android.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=669" title="マルチタッチのマルチデバイスでマルチユーザー" />
    <id>tag:faces.jp,2010://1.669</id>
    
    <published>2010-06-12T10:10:11Z</published>
    <updated>2010-06-12T11:01:02Z</updated>
    
    <summary>iPhone iPad Android で HTML5 と Ajax、サーバーサ...</summary>
    <author>
        <name>ao</name>
        
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        <![CDATA[iPhone iPad Android で HTML5 と Ajax、サーバーサイドで PHP の<a href="http://jp.php.net/manual/ja/ref.sem.php">シェアメモリ</a>を使います。]]>
        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
-->
</style>

<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/q1RLvaMgauo&hl=ja&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/q1RLvaMgauo&hl=ja&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>
<div class="ao"><p>
PC でも HTML5 ブラウザが動けば参加できます。（マルチタッチちがうけど）<br/>
ガラパゴスの方のケータイでも Ajax 部分を FlashLite で作ればいけますね。<br/>
ソース（といっても中身は適当）<br/>
つ<a href="http://faces.jp/files/ao/0612/0612ScatterSample.zip">0612ScatterSample.zip</a>

</p>
]]>
    </content>
</entry>
<entry>
    <title>HTML5 : TouchController</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2010/05/javascript_pc.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=668" title="HTML5 : TouchController" />
    <id>tag:faces.jp,2010://1.668</id>
    
    <published>2010-05-24T01:47:57Z</published>
    <updated>2010-05-24T03:46:22Z</updated>
    
    <summary>mouse 系のイベントを touch にバイパスさせれば、スマートフォン用コン...</summary>
    <author>
        <name>ao</name>
        
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        mouse 系のイベントを touch にバイパスさせれば、スマートフォン用コンテンツもPCブラウザでプレビューできます。
        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
-->
</style><div class="ao"><p>
以下の TouchController クラス（書いている内容は mouse のドラッグ＆ドロップ操作）を継承させて ViewController を作れば簡単なものはすぐ作れます。<br />
しっかり書けば iPhone, Android から PC ともに互換するコンテンツなんかも作れそうな気がします。



</p>

<table><td><p>サンプル<br /><a href="http://faces.jp/files/ao/0524/"><img src="http://faces.jp/files/ao/0524/gyorol/5.png"/></a><br />画像をクリック</p></td><td><p>
Canvas 版サンプル<br /><a href="http://faces.jp/files/ao/0524/canvas.html"><img src="http://faces.jp/files/ao/0524/gyorol/5.png"/></a><br />画像をクリック</p></td></table>
<pre>

// IE 使わないならこの分岐いらない
if (true && document.all && document.attachEvent) {
	function eventPreventDefault(){
		event.returnValue = false;
	}
	//http://yupotan.sppd.ne.jp/web/dom2-msie.html
	document.addEventListener=function(key,func,b) {
		this.attachEvent("on"+key, function(){
			return func({
				target			:event.srcElement,
				cancelBubble	:event.cancelBubble,
				pageX			:event.clientX,
				pageY			:event.clientY,
	 			preventDefault	:eventPreventDefault
			});
		});
	}
	document.removeEventListener=function(key,func,b) {
		this.detachEvent("on"+key, func);
	}
}

$class('TouchController',{
	initTouch:function(){
		if( navigator.userAgent.search(/(iPhone|Android)/) != -1 ){
			document.addEventListener("touchstart",	this.touchesBegan.bind(this), false);
			document.addEventListener("touchmove",	this.touchesMoved.bind(this), false);
			document.addEventListener("touchend",	this.touchesEnded.bind(this), false);		
		}else{
			$('body').style.cursor = "pointer";
			this.initMouse();
		}
	},
	initMouse:function(){
		document.addEventListener('mousedown',	function(e){
			this.isDragging	= true;
			e.touches = [e];
			this.touchesBegan(e);
		}.bind(this), false);
		document.addEventListener('mousemove',	function(e){
			if (this.isDragging) {
				e.touches = [e];
				this.touchesMoved(e);
			}
		}.bind(this), false);
		document.addEventListener('mouseup',	function(e){
			if (this.isDragging) {
				this.isDragging = false;
				e.touches = [e];
				this.touchesEnded(e)
			}
		}.bind(this), false);
	},
	touchesBegan:function(){},
	touchesMoved:function(){},
	touchesEnded:function(){}

});
</pre>
</div>]]>
    </content>
</entry>
<entry>
    <title>JS is OOP : 継承順序を意識しない class と extends</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2010/05/js_is_oop_class_extends.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=667" title="JS is OOP : 継承順序を意識しない class と extends" />
    <id>tag:faces.jp,2010://1.667</id>
    
    <published>2010-05-13T02:45:35Z</published>
    <updated>2010-05-13T02:57:55Z</updated>
    
    <summary>JavaScript には include や import がなく、かわりに ...</summary>
    <author>
        <name>ao</name>
        
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        JavaScript には include や import がなく、かわりに html のヘッダーにファイルの数だけタグをぽちぽち書きます。
クラスでファイル分けすると量が半端ないので、手作業より自動化ツールを作ったほうが早いというもんですが、自動化するとクラス継承にまつわる読み込み順序がネックになってきます。
        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
-->
</style><div class="ao"><p>クラス継承順を整理して考えるより、js上でクラス継承キューを作った方が早いです。
</p>
<p>用例</p>
<pre>

$class('ThumbQueueView',$extends('View',{
	draw:function(){
		$('Body').innerHTML = '&lt;div id="ThumbQueueAsExternal"&gt;&lt;/div&gt;';
		this.drawSWF({
			name	:'img/swf/ThumbQueue.swf?'+time(),
			id	:'ThumbQueueAsExternal',
			width	:'100%',
			height	:'100%',
			vars	:{}
		});
	}
}));

//↓継承する View クラスが後に来てても通る

$class('View',{
	draw:function(){},
	drawSWF:function(swf){
		swfobject.embedSWF(
			swf.name, swf.id, swf.width,swf.height,
			'9.0.0', 'img/swf/expressInstall.swf',swf.vars,
			{allowFullScreen:'true',allowScriptAccess:'always'},
			{id:swf.id,align:'middle'}
		);
	}
}

var view = new ThumbQueueView();
view.draw();

</pre>

<p>ソース</p>

<pre>


//要 prototype.js

var $classes	= {};
var $classQueue	= {};

function forEach(obj,func){
	if(Object.isArray(obj)) {
		for(var i=0;i&lt;obj.length;i++) {
			if (obj[i]) {
				func(i, obj[i])
			}
		}
	}else {
		for(var key in obj){
			func(key,obj[key])
		}
	}
}

function $class(name,obj){
	if(Object.isArray(obj)){
		if(!(obj[0] in $classQueue)) $classQueue[obj[0]] = [];
		$classQueue[obj[0]].push({
			className:name,
			superClassName:obj[0],
			contents:obj[1]
		});
	}else{
		var c = ('isSubclassOf' in obj)?obj:$extends(null,obj);
		c.className		= name;
		$classes[name]	= c;
		window[name]	= c;
		
		if (name in $classQueue) {
			forEach($classQueue[name], function(i, value){
				if (value.className) {
					$class(value.className, $extends(value.superClassName, value.contents))
				}
			});
			delete ($classQueue[name]);
		}
	}
}

function $extends(parentClass,classMethods){
	
	var superClassEnable = true;
	if(Object.isString(parentClass)){
		if(parentClass in window){
			var superClass = window[parentClass];
		}else{
			superClassEnable = false;
		}
	}else{
		superClass = parentClass
	}
	
	if(superClassEnable){
		var c = Class.create();
		if(superClass) Object.extend(c.prototype, superClass.prototype);
		Object.extend(c.prototype, classMethods);
		c.superClass = superClass;
		c.isSubclassOf = function(object){
			if(!this.superClass)	return false;
			if(this.superClass == object)	return true;
			return this.superClass.isSubclassOf(object)
		}
		c.prototype.self = c;
		return c;
	}else{
		return $A(arguments);
	}
}


</pre>
</div>]]>
    </content>
</entry>
<entry>
    <title>FlashPlayer10.1でバグレポート</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2010/03/flashplayer101.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=665" title="FlashPlayer10.1でバグレポート" />
    <id>tag:faces.jp,2010://1.665</id>
    
    <published>2010-03-03T10:39:03Z</published>
    <updated>2010-03-03T10:41:24Z</updated>
    
    <summary>「開発時にはクラッシュレポートみたいなのを表示して、エラーが出た状況を書き込んで...</summary>
    <author>
        <name>maegawa</name>
        <uri>/2006/07/post_2.html</uri>
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        「開発時にはクラッシュレポートみたいなのを表示して、エラーが出た状況を書き込んでもらえれば、ありがたい。そういうライブラリを誰か作ってほしい。」
        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
-->
</style>
<div class="ao">
<p>
などと、弊社のババが<a href="http://twitter.com/kampei/status/9667485941">呟き</a>ました。<br>
<br>
ローカルマシンでは正しく動作するのに、別マシンで動かしたら「ActionScriptエラーが発生しました」というポップアップ…。そんなエラーが発生したクライアントの動作環境が分かれば、環境依存するような問題を解決しやすくなります。<br>
<br>
Flash Player 10.1からグローバルなエラー処理が可能となります。<br>つまり、クライアントで発生したエラー内容を記録する仕組みを実現できるようになりました。<br>
<br>
今回は、この仕組みを AS3 + GAE/J（GoogleAppEngin for Java）を利用して簡単に構築してみようと思います。<br>
※開発には、<a href="http://labs.adobe.com/downloads/flashplayer10.html">FlashPlayer10.1 beta 3</a>（2010/03/02現在）をインストールする必要があります。<br>※<a href="http://code.google.com/intl/ja/appengine/">GAE/J</a>を開発する環境も別途必要になります。<br>
<br>
AS3 : UncaughtErrorMonitorクラス
</p>
<pre>
package{

	import flash.display.DisplayObject;
	import flash.events.ErrorEvent;
	import flash.events.UncaughtErrorEvent;
	import flash.external.ExternalInterface;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import flash.net.sendToURL;
	import flash.system.Capabilities;

	/**
	 * エラー補足モニタークラス
	 * 
	 * グローバルエラーを監視し、エラーが発生した場合に内容をポストします
	 * 
	 * @author maegawa@bascule
	 */	
	public class UncaughtErrorMonitor{
		
		/**
		 * コンストラクタ
		 * @param clazz
		 */		
		public function UncaughtErrorMonitor( clazz:PrivateClass ){
			// インスタンスは生成させない
		}
		/**
		 * 初期化する
		 * @param root	:ドキュメントクラス
		 */		 
		public static function init( root:DisplayObject ):void{
			
			if( root && root.loaderInfo ){
				root.loaderInfo.uncaughtErrorEvents.addEventListener( UncaughtErrorEvent.UNCAUGHT_ERROR, function( e:UncaughtErrorEvent ):void{
				
					var errorID	:uint = 0;
					var type	:String = "";
					var message	:String = "";
					var location:String = "";
					
					if( e.error is Error ){	// Errorを捕捉した場合
						var error:Error = e.error as Error;
						errorID = error.errorID;
						type = error.name;
						message = error.message;
						location = error.getStackTrace();
					}else
					if( e.error is ErrorEvent ){	// ErrorEventを捕捉した場合
						var event:ErrorEvent = e.error as ErrorEvent;
						errorID = event.errorID;
						type = event.type; 
						message = event.text;
					}else{
						return;	// Error、ErrorEventを補足した場合は処理を中断
					}
					
					var url:String = "http://GAEアプリID.appspot.com/regist";
					
					var variables:URLVariables = new URLVariables;
						variables.errorID = errorID;		// エラーID
						variables.type = type;			// エラータイプ
						variables.message = message;		// エラーメッセージ
						variables.location = location;		// エラー発生場所
						variables.swf = Capabilities.version;	// SWFのバージョン判定
						variables.userAgent = getUserAgent();	// UserAgent判定
						
					var request:URLRequest = new URLRequest( url );
						request.data = variables;
						request.method = URLRequestMethod.POST;
					
					try{
						sendToURL( request );
					}catch( e:Error ){
					}
				} );
			}
		}
		/**
		 * ユーザーエージェントを取得する
		 * @return 
		 */		
		private static function getUserAgent():String{
			try{
				if( ExternalInterface.available ){
					return ExternalInterface.call( "function(){ return navigator.userAgent; }" );
				}
			}catch( e:Error ){}
			
			return "unknow";
		}
	}
}
class PrivateClass{}
</pre>
<p>
続いて、サーバー側を準備します。<br>
<br>
GAE : UncaughterrorServletクラス
</p>
<pre>
package jp.bascule;

import java.io.IOException;
import java.util.Date;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Transaction;

@SuppressWarnings("serial")
public class RegistUncaughtErrorServlet extends HttpServlet {
	
	public void doGet( HttpServletRequest req, HttpServletResponse res ) throws IOException {
		res.sendError( 400 );
	}
	
	public void doPost( HttpServletRequest req, HttpServletResponse res ) throws IOException {
		
		try {
			String errorID = req.getParameter( "errorID" );// エラーID
			String type = req.getParameter( "type" );// エラータイプ
			String message = req.getParameter( "" );// エラーメッセージ
			String location = req.getParameter( "location" );// エラー発生場所
			String swf = req.getParameter( "swf" );// SWFのバージョン判定
			String userAgent = req.getParameter( "userAgent" );// UserAgent判定
			
			Date date = new Date();
			long time = date.getTime();
			//
			Entity entity = new Entity( "UncaughtError" );
			entity.setProperty( "appkey", appkey );
			entity.setProperty( "error_id", errorID );
			entity.setProperty( "error_type", type );
			entity.setProperty( "error_message", message );
			entity.setProperty( "error_location", location );
			entity.setProperty( "swf_version", swf );
			entity.setProperty( "user_agent", userAgent );
			entity.setProperty( "datetime", time );
			
			
			DatastoreService service = DatastoreServiceFactory.getDatastoreService();
			Transaction transaction = service.beginTransaction();
			try {
				service.put(transaction, entity);
				transaction.commit();
			} finally {
				if (transaction.isActive())
					transaction.rollback();
			}

			res.getWriter().print( "success" );
			
		} catch (Exception e) {
			res.getWriter().print( "error" );
			e.printStackTrace();
		}
	}
}
</pre>
<p>
GAE:web.xml
</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"&gt;
	&lt;servlet&gt;
		&lt;servlet-name&gt;RegistUncaughtError&lt;/servlet-name&gt;
		&lt;servlet-class&gt;jp.bascule.RegistUncaughtErrorServlet&lt;/servlet-class&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;RegistUncaughtError&lt;/servlet-name&gt;
		&lt;url-pattern&gt;/regist&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
	&lt;welcome-file-list&gt;
		&lt;welcome-file&gt;index.html&lt;/welcome-file&gt;
	&lt;/welcome-file-list&gt;
&lt;/web-app&gt;
</pre>
<p>
この内容をGAEにデプロイすれば完了です。<br>
<br>
AS3:Testクラス
</p>
<pre>
package{

	import flash.display.Sprite;
	import flash.events.ErrorEvent;
	
	/**
	 * Testクラス
	 * 
	 * UncaughtErrorMonitorクラスの動作をチェックします。
	 * 意図的にError、ErrorEventをスローさせます。
	 */	
	public class Test extends Sprite{
		
		public function Test(){
			// モニタリングを開始
			UncaughtErrorMoniter.init( this );
			// Errorの場合
			throw new Error( "エラーが発生！" );
			// ErrorEventの場合
			//throw new ErrorEvent( ErrorEvent.ERROR, false, false, "エラーイベントが発生！" );
		}
	}
}
</pre>
<p>
<br>
こんな感じで呼び出しておけば、クライアント側でエラーが発生した場合に勝手に内容がポストされます。<br>いくつかのプロジェクトで仕組みを使いまわすのであれば、アプリケーション識別子を引数に加えてあげればいいだけです。さらに、画面サイズ、ネットワーク環境など、その他の情報も記録しておけば、よりスムーズに問題を解決できそうです。<br>
<br>
GAEの管理画面にはDatastoreViewerというデータを確認する画面があるので、一覧表示する画面を用意する必要もありません。GAEは無料で使用可能ですが、データ保存容量には限界があります。とくに情報を残す必要がないのであれば、cronを利用して定期的に内容を削除すればよいと思います。
</p>
</div>]]>
    </content>
</entry>
<entry>
    <title> FlashLite1.1：SHA1する</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2009/10/flashlite11sha1.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=664" title=" FlashLite1.1：SHA1する" />
    <id>tag:faces.jp,2009://1.664</id>
    
    <published>2009-10-25T14:14:12Z</published>
    <updated>2009-10-25T14:51:15Z</updated>
    
    <summary>手元のケータイでしか確認してませんが実機でも動きます。...</summary>
    <author>
        <name>ao</name>
        
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        手元のケータイでしか確認してませんが実機でも動きます。
        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
-->
</style><div class="ao"><p>

前回の <a href="http://faces.jp/2009/10/flash_lite_md5.html">md5</a> では FlashLite の Infinity に屈したわけですが、今回は対策を練ってから。<br/>
<br/>
int の上位ビットに数値がかかると、桁があふれて Infinity になるため、<br/>
内部で int を 1/16 したまま扱ってしまうような設計にしました。<br/>
ソース内で xint と記述しているのがそうですが、<br/>
int の符号を再現するために Windows の「電卓」がかなり役に立ちましたw<br/>
<br/>
<img alt="sha1.swf" src="http://qrcode.jp/qr?q=http%3a%2f%2ffaces.jp%2f2009%2f10%2f25%2fsha1.swf" width="148" height="148" /></a><br/>
<a href="http://faces.jp/2009/10/25/sha1.swf">http://faces.jp/2009/10/25/sha1.swf</a><br/>
<a href="http://faces.jp/2009/10/25/1025_sha1.zip">ソースをダウンロード</a><br/>
<br/>
符号再現のあたりでビット演算のために2の乗数での剰除を繰り返してますが、<br/>
負の数に対しての "%" 演算結果が、DeviceCentral(FL1.1,FL2.1) と実機で違ってる。<br/>
実機の結果は Flash4(PC) で走らせた結果と同じになるんだけど、これはCS3だからかも？<br/>
<br/>
また、md5 では50KBを超えた swf も、call のおかげで今回は10KB以下に抑えられましたが<br/>
最後に残念なお知らせというか、期待通りのオチがあります。<br/>
<br/>
OAuth のようなことをしたくてこれを作ったのですが、<br/>
どんな短い String でも実機上での hash に10秒以上かかります。<br/>
ケータイはキー押下すぐのタイミングでしかリクエストを送れないので、<br/>
これじゃ全然間に合いません。<br/>
<br/>
一番処理を食っているのは int のエミュレーションですが<br/>
FL2 であれば十分実用に足るものが作れるに違いないと我々は信じてやみません。<br/>
</p>
</div>]]>
    </content>
</entry>
<entry>
    <title>FlashLite1.1：SLGの戦略AIを作る</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2009/10/flashlite11slgai.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=663" title="FlashLite1.1：SLGの戦略AIを作る" />
    <id>tag:faces.jp,2009://1.663</id>
    
    <published>2009-10-17T08:13:30Z</published>
    <updated>2011-01-14T02:53:54Z</updated>
    
    <summary>距離移動コストと敵の強さから費用対効果を計算してそれぞれ行動します。...</summary>
    <author>
        <name>ao</name>
        
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        距離移動コストと敵の強さから費用対効果を計算してそれぞれ行動します。
        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
-->
</style><div class="ao"><p>
<img alt="slg.gif" src="http://faces.jp/2009/10/17/slg.gif" width="240" height="320" />　
<img src="http://qrcode.jp/qr?q=http%3a%2f%2ffaces.jp%2f2009%2f10%2f17%2fslg.swf" width="148"/><br />
実装してませんが、複数ユニットで攻撃するようなチームプレイ戦略とかを<br />
算出できるようになれば面白くなりそう。<br />
<a href="http://faces.jp/2009/10/17/1017_slg.zip">zipファイル</a><br />
※ちなみに as/init.as の<br />
//playerAsCpu = "xooo";<br />
のコメントをはずすと青軍を操作できます。
</p>
<pre>

//thinkTarget.as
//攻撃のROI計算

targetBin = "";
_maxYummy = 0;

for(i = 1; i &lt;= playerCount; i++ ) {
	if (i != player) {
		_units	= eval("units" add i);
		while (length(_units) &gt; 0) {
			_unitId		= i * 1000 + ord(subString(_units, 1,	1)) - 0x80;
			x			= getProperty("map/unit" add _unitId, _x);
			y			= getProperty("map/unit" add _unitId, _y);
			_unitHp		= ord(subString(_units, 3,	1)) - 0x80;
			
			_index		= 1 + x + y * mapWidth;
			_minCost	= -1;
			
			if (y &gt; 0) {
				_cost		= ord(subString(costMap, _index - mapWidth, 1)) - 0x80;
				if ((_cost &gt;= 0) and ((_cost &lt; _minCost) or (_minCost &lt; 0))) {
					_minCost	= _cost;
					s			= mbChr(0x80 + x) add mbChr(0x80 + y - 1);
					_direction	= 1;
				}	
			}
			if (x &lt; mapWidth-1) {
				_cost		= ord(subString(costMap, _index + 1, 1)) - 0x80;
				if ((_cost &gt;= 0) and ((_cost &lt; _minCost) or (_minCost &lt; 0))) {
					_minCost	= _cost;
					s			= mbChr(0x80 + x + 1) add mbChr(0x80 + y);
					_direction	= 2;
				}
			}
			if (y &lt; mapHeight-1) {
				_cost		= ord(subString(costMap, _index + mapWidth, 1)) - 0x80;
				if ((_cost &gt;= 0) and ((_cost &lt; _minCost) or (_minCost &lt; 0))) {
					_minCost	= _cost;
					s			= mbChr(0x80 + x) add mbChr(0x80 + y + 1);
					_direction	= 3;
				}
			}
			if (x &gt; 0) {
				_cost		= ord(subString(costMap, _index - 1, 1)) - 0x80;
				if ((_cost &gt;= 0) and ((_cost &lt; _minCost) or (_minCost &lt; 0))) {
					_minCost	= _cost;
					s			= mbChr(0x80 + x - 1) add mbChr(0x80 + y);
					_direction	= 4;
				}
			}
			
			if (_minCost &gt;= 0) {
				_yummy = (unitHp/_unitHp)/(_minCost/unitMove+1)
				if (_yummy &gt; _maxYummy) {
					_maxYummy	= _yummy;
					targetBin	= mbChr(0x80 + i) add subString(_units, 1, 3) add s add mbChr(0x80 + _direction);
				}
			}else {
				//攻撃不可
			}
			_units	= subString(_units, 4);
		}
	}
}
</pre>
<pre>

//thinkCost.as
//コスト計算（マップ移動）

//-1 未調査 -1 囲まれて移動不可エリアか未調査エリア
//-2 距離が大きすぎ 
//-3 超えられないもの
//-4 敵	

_timer = getTimer() + 1000 / 12;

while((length(_stack) &gt; 0) and (_timer &gt; getTimer())) {
	x			= ord(subString(_stack, 1, 1)) - 0x80;
	y			= ord(subString(_stack, 2, 1)) - 0x80;
	_cost		= ord(subString(_stack, 3, 1)) - 0x80;
	_direction	= ord(subString(_stack, 4, 1)) - 0x80;
	_stack		= subString(_stack, 5);
		
	_index		= 1 + x + y * mapWidth;
	i			= ord(subString(costMap, _index, 1)) - 0x80;
	//速度優先最適化
	//if (i &gt; -2) {
		_cost		+= ord(subString(moveCostsByChip, ord(subString(fieldMap, _index, 1)) - 0x80, 1)) - 0x80;
		if ((_cost &lt; i) or (i == -1)) {
			if (_cost &gt; unitMove * 2) {
				costMap	= subString(costMap, 1, _index - 1 ) add mbChr(0x80 - 2)			add subString(costMap, _index + 1);
			}else {
				costMap	= subString(costMap, 1, _index - 1 ) add mbChr(0x80 + _cost)		add subString(costMap, _index + 1);
				moveMap = subString(moveMap, 1, _index - 1 ) add mbChr(0x80 + _direction)	add subString(moveMap, _index + 1);
				switch(false) {
					case(_direction == 3):
						if (y &gt; 0) {
							if (ord(subString(costMap, _index - mapWidth, 1)) - 0x80 &gt; -2) {
								_stack = _stack add mbChr(0x80 + x)		add mbChr(0x80 + y - 1)	add mbChr(0x80 + _cost) add mbChr(0x80 + 1);
							}
						}
					case(_direction == 4):
						if (x &lt; mapWidth - 1) {
							if (ord(subString(costMap, _index + 1, 1)) - 0x80 &gt; -2) {
								_stack = _stack add mbChr(0x80 + x + 1)	add mbChr(0x80 + y)		add mbChr(0x80 + _cost) add mbChr(0x80 + 2);
							}
						}
					case(_direction == 1):
						if (y &lt; mapHeight - 1) {
							if (ord(subString(costMap, _index + mapWidth, 1)) - 0x80 &gt; -2) {
								_stack = _stack add mbChr(0x80 + x)		add mbChr(0x80 + y + 1)	add mbChr(0x80 + _cost) add mbChr(0x80 + 3);
							}
						}
					case(_direction == 2):
						if (x &gt; 0) {
							if (ord(subString(costMap, _index - 1, 1)) - 0x80 &gt; -2) {
								_stack = _stack add mbChr(0x80 + x - 1)	add mbChr(0x80 + y)		add mbChr(0x80 + _cost) add mbChr(0x80 + 4);
							}
						}
				}
			}			

		}	
		
	//}
}
</pre>
</div>]]>
    </content>
</entry>
<entry>
    <title>Flash Lite で MD5 を作ってみた。</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2009/10/flash_lite_md5.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=662" title="Flash Lite で MD5 を作ってみた。" />
    <id>tag:faces.jp,2009://1.662</id>
    
    <published>2009-10-15T07:40:25Z</published>
    <updated>2009-10-16T05:22:40Z</updated>
    
    <summary>残念ながら FlashLite2.0 機種上の FlashLite1.1 でしか...</summary>
    <author>
        <name>ao</name>
        
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        残念ながら FlashLite2.0 機種上の FlashLite1.1 でしか動きません。

        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
-->
</style><div class="ao"><p>ケータイ SWF からリクエストする際の内容を証明できるようにしたかったんですが、<br />メモリは食わないものの、スクリプトだけで<font color="red"> SWF が <b>50KB</b> 超えます。</font><br />
逆にFL2.x以降ならシフトローテート、関数、配列、論理演算を使って短く記述できるので、<br />
SHA1とかも可能と思う。FlashLite2.0以降であれば、 OpenSocial なリクエストもできそう。<br />
Fla はここに <a href="http://faces.jp/files/ao/20091015_md5/fl1md5.zip">http://faces.jp/files/ao/20091015_md5/fl1md5.zip</a></p>
<p>com.adobe.crypto.MD5 を参考にしたんですが、中身は AND XOR など論理演算が中心で<br />
アセンブラで組みこめそうな内容でした</p>
<pre>

//md5Init.as

len = length(str);
s = str add mbChr(0x80)

blocks		= ''
blocksMask	= ''

for(i = 0; i &lt;= len; i += 4 ) {
	for (j = 4; j&gt;0; j-- ) {
		c = subString(s, i + j, 1)
		if (c eq '') {
			blocks		= blocks add '.'
			blocksMask	= blocksMask add '0'
		}else {
			blocks		= blocks add c
			blocksMask	= blocksMask add '1'
		}
	}
}

i = (int((len * 8 + 0x40) / 0x0200) * 0x10 + 0x0e) * 4

while(length(blocks) &lt; i) {
	blocks		= blocks add '.';
	blocksMask	= blocksMask add '0'	
}

for(i = 0x01000000; i &gt;=1; i /= 0x0100 ) {
	byte = int((len*8) / i) % 0x0100;
	if (byte == 0) {
		blocks		= blocks add '.';
		blocksMask	= blocksMask add '0'
	}else {
		blocks		= blocks add mbChr(byte);
		blocksMask	= blocksMask add '1'
	}
}

a = 1732584193;
b = -271733879;
c = -1732584194;
d = 271733878;

s = 4294967296;//0x100000000
n = 0x80000000;

p = 0;
</pre>
<pre>

//md5Encode.as


for (j = 0; j &lt; 16; j++ ) {
	name		= 'x' add subString('0123456789ABCDEF',j+1,1)
	eval(name)	= 0;
	for (k = 0x01000000; k &gt;= 1; k /= 0x0100 ) {
		if (subString(blocksMask, p+1, 1) &gt; 0) {
			eval(name) += ord(subString(blocks, p+1, 1)) * k
		}
		p++
	}
}

aa = a;
bb = b;
cc = c;
dd = d;	

v=0;for(i=1;i&lt;s;i*=2){v+=(((int(b/i)%2)&&(int(c/i)%2))||((!(int(b/i)%2))&&(int(d/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+x0-680876936;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x2000000)*0x80)+int(((v&lt;0)?v+s :v)/0x2000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(a/i)%2)&&(int(b/i)%2))||((!(int(a/i)%2))&&(int(c/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+x1-389564586;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x100000)*0x1000)+int(((v&lt;0)?v+s :v)/0x100000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(d/i)%2)&&(int(a/i)%2))||((!(int(d/i)%2))&&(int(b/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+x2+606105819;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x8000)*0x20000)+int(((v&lt;0)?v+s :v)/0x8000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(c/i)%2)&&(int(d/i)%2))||((!(int(c/i)%2))&&(int(a/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+x3-1044525330;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x400)*0x400000)+int(((v&lt;0)?v+s :v)/0x400)+c;	if(b&gt;n)b-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(b/i)%2)&&(int(c/i)%2))||((!(int(b/i)%2))&&(int(d/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+x4-176418897;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x2000000)*0x80)+int(((v&lt;0)?v+s :v)/0x2000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(a/i)%2)&&(int(b/i)%2))||((!(int(a/i)%2))&&(int(c/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+x5+1200080426;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x100000)*0x1000)+int(((v&lt;0)?v+s :v)/0x100000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(d/i)%2)&&(int(a/i)%2))||((!(int(d/i)%2))&&(int(b/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+x6-1473231341;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x8000)*0x20000)+int(((v&lt;0)?v+s :v)/0x8000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(c/i)%2)&&(int(d/i)%2))||((!(int(c/i)%2))&&(int(a/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+x7-45705983;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x400)*0x400000)+int(((v&lt;0)?v+s :v)/0x400)+c;	if(b&gt;n)b-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(b/i)%2)&&(int(c/i)%2))||((!(int(b/i)%2))&&(int(d/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+x8+1770035416;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x2000000)*0x80)+int(((v&lt;0)?v+s :v)/0x2000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(a/i)%2)&&(int(b/i)%2))||((!(int(a/i)%2))&&(int(c/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+x9-1958414417;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x100000)*0x1000)+int(((v&lt;0)?v+s :v)/0x100000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(d/i)%2)&&(int(a/i)%2))||((!(int(d/i)%2))&&(int(b/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+xA-42063;		if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x8000)*0x20000)+int(((v&lt;0)?v+s :v)/0x8000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(c/i)%2)&&(int(d/i)%2))||((!(int(c/i)%2))&&(int(a/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+xB-1990404162;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x400)*0x400000)+int(((v&lt;0)?v+s :v)/0x400)+c;	if(b&gt;n)b-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(b/i)%2)&&(int(c/i)%2))||((!(int(b/i)%2))&&(int(d/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+xC+1804603682;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x2000000)*0x80)+int(((v&lt;0)?v+s :v)/0x2000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(a/i)%2)&&(int(b/i)%2))||((!(int(a/i)%2))&&(int(c/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+xD-40341101;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x100000)*0x1000)+int(((v&lt;0)?v+s :v)/0x100000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(d/i)%2)&&(int(a/i)%2))||((!(int(d/i)%2))&&(int(b/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+xE-1502002290;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x8000)*0x20000)+int(((v&lt;0)?v+s :v)/0x8000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(c/i)%2)&&(int(d/i)%2))||((!(int(c/i)%2))&&(int(a/i)%2)))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+xF+1236535329;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x400)*0x400000)+int(((v&lt;0)?v+s :v)/0x400)+c;	if(b&gt;n)b-=s;

v=0;for(i=1;i&lt;s;i*=2){v+=(((int(b/i)%2)&&(int(d/i)%2))||((int(c/i)%2)&&(!(int(d/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+x1-165796510;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x8000000)*0x20)+int(((v&lt;0)?v+s :v)/0x8000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(a/i)%2)&&(int(c/i)%2))||((int(b/i)%2)&&(!(int(c/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+x6-1069501632;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x800000)*0x200)+int(((v&lt;0)?v+s :v)/0x800000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(d/i)%2)&&(int(b/i)%2))||((int(a/i)%2)&&(!(int(b/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+xB+643717713;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x40000)*0x4000)+int(((v&lt;0)?v+s :v)/0x40000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(c/i)%2)&&(int(a/i)%2))||((int(d/i)%2)&&(!(int(a/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+x0-373897302;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x1000)*0x100000)+int(((v&lt;0)?v+s :v)/0x1000)+c;	if(b&gt;n)b-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(b/i)%2)&&(int(d/i)%2))||((int(c/i)%2)&&(!(int(d/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+x5-701558691;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x8000000)*0x20)+int(((v&lt;0)?v+s :v)/0x8000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(a/i)%2)&&(int(c/i)%2))||((int(b/i)%2)&&(!(int(c/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+xA+38016083;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x800000)*0x200)+int(((v&lt;0)?v+s :v)/0x800000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(d/i)%2)&&(int(b/i)%2))||((int(a/i)%2)&&(!(int(b/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+xF-660478335;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x40000)*0x4000)+int(((v&lt;0)?v+s :v)/0x40000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(c/i)%2)&&(int(a/i)%2))||((int(d/i)%2)&&(!(int(a/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+x4-405537848;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x1000)*0x100000)+int(((v&lt;0)?v+s :v)/0x1000)+c;	if(b&gt;n)b-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(b/i)%2)&&(int(d/i)%2))||((int(c/i)%2)&&(!(int(d/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+x9+568446438;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x8000000)*0x20)+int(((v&lt;0)?v+s :v)/0x8000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(a/i)%2)&&(int(c/i)%2))||((int(b/i)%2)&&(!(int(c/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+xE-1019803690;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x800000)*0x200)+int(((v&lt;0)?v+s :v)/0x800000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(d/i)%2)&&(int(b/i)%2))||((int(a/i)%2)&&(!(int(b/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+x3-187363961;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x40000)*0x4000)+int(((v&lt;0)?v+s :v)/0x40000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(c/i)%2)&&(int(a/i)%2))||((int(d/i)%2)&&(!(int(a/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+x8+1163531501;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x1000)*0x100000)+int(((v&lt;0)?v+s :v)/0x1000)+c;	if(b&gt;n)b-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(b/i)%2)&&(int(d/i)%2))||((int(c/i)%2)&&(!(int(d/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+xD-1444681467;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x8000000)*0x20)+int(((v&lt;0)?v+s :v)/0x8000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(a/i)%2)&&(int(c/i)%2))||((int(b/i)%2)&&(!(int(c/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+x2-51403784;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x800000)*0x200)+int(((v&lt;0)?v+s :v)/0x800000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(d/i)%2)&&(int(b/i)%2))||((int(a/i)%2)&&(!(int(b/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+x7+1735328473;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x40000)*0x4000)+int(((v&lt;0)?v+s :v)/0x40000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(c/i)%2)&&(int(a/i)%2))||((int(d/i)%2)&&(!(int(a/i)%2))))*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+xC-1926607734;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x1000)*0x100000)+int(((v&lt;0)?v+s :v)/0x1000)+c;	if(b&gt;n)b-=s;

v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(b/i)%2)+(int(c/i)%2))%2)+(int(d/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+x5-378558;		if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x10000000)*0x10)+int(((v&lt;0)?v+s :v)/0x10000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(a/i)%2)+(int(b/i)%2))%2)+(int(c/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+x8-2022574463;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x200000)*0x800)+int(((v&lt;0)?v+s :v)/0x200000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(d/i)%2)+(int(a/i)%2))%2)+(int(b/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+xB+1839030562;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x10000)*0x10000)+int(((v&lt;0)?v+s :v)/0x10000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(c/i)%2)+(int(d/i)%2))%2)+(int(a/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+xE-35309556;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x200)*0x800000)+int(((v&lt;0)?v+s :v)/0x200)+c;	if(b&gt;n)b-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(b/i)%2)+(int(c/i)%2))%2)+(int(d/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+x1-1530992060;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x10000000)*0x10)+int(((v&lt;0)?v+s :v)/0x10000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(a/i)%2)+(int(b/i)%2))%2)+(int(c/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+x4+1272893353;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x200000)*0x800)+int(((v&lt;0)?v+s :v)/0x200000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(d/i)%2)+(int(a/i)%2))%2)+(int(b/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+x7-155497632;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x10000)*0x10000)+int(((v&lt;0)?v+s :v)/0x10000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(c/i)%2)+(int(d/i)%2))%2)+(int(a/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+xA-1094730640;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x200)*0x800000)+int(((v&lt;0)?v+s :v)/0x200)+c;	if(b&gt;n)b-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(b/i)%2)+(int(c/i)%2))%2)+(int(d/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+xD+681279174;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x10000000)*0x10)+int(((v&lt;0)?v+s :v)/0x10000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(a/i)%2)+(int(b/i)%2))%2)+(int(c/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+x0-358537222;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x200000)*0x800)+int(((v&lt;0)?v+s :v)/0x200000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(d/i)%2)+(int(a/i)%2))%2)+(int(b/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+x3-722521979;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x10000)*0x10000)+int(((v&lt;0)?v+s :v)/0x10000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(c/i)%2)+(int(d/i)%2))%2)+(int(a/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+x6+76029189;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x200)*0x800000)+int(((v&lt;0)?v+s :v)/0x200)+c;	if(b&gt;n)b-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(b/i)%2)+(int(c/i)%2))%2)+(int(d/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+x9-640364487;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x10000000)*0x10)+int(((v&lt;0)?v+s :v)/0x10000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(a/i)%2)+(int(b/i)%2))%2)+(int(c/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+xC-421815835;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x200000)*0x800)+int(((v&lt;0)?v+s :v)/0x200000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(d/i)%2)+(int(a/i)%2))%2)+(int(b/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+xF+530742520;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x10000)*0x10000)+int(((v&lt;0)?v+s :v)/0x10000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((((int(c/i)%2)+(int(d/i)%2))%2)+(int(a/i)%2))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+x2-995338651;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x200)*0x800000)+int(((v&lt;0)?v+s :v)/0x200)+c;	if(b&gt;n)b-=s;

v=0;for(i=1;i&lt;s;i*=2){v+=(((int(c/i)%2)+((int(b/i)%2)||(!(int(d/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+x0-198630844;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x4000000)*0x40)+int(((v&lt;0)?v+s :v)/0x4000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(b/i)%2)+((int(a/i)%2)||(!(int(c/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+x7+1126891415;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x400000)*0x400)+int(((v&lt;0)?v+s :v)/0x400000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(a/i)%2)+((int(d/i)%2)||(!(int(b/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+xE-1416354905;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x20000)*0x8000)+int(((v&lt;0)?v+s :v)/0x20000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(d/i)%2)+((int(c/i)%2)||(!(int(a/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+x5-57434055;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x800)*0x200000)+int(((v&lt;0)?v+s :v)/0x800)+c;	if(b&gt;n)b-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(c/i)%2)+((int(b/i)%2)||(!(int(d/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+xC+1700485571;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x4000000)*0x40)+int(((v&lt;0)?v+s :v)/0x4000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(b/i)%2)+((int(a/i)%2)||(!(int(c/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+x3-1894986606;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x400000)*0x400)+int(((v&lt;0)?v+s :v)/0x400000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(a/i)%2)+((int(d/i)%2)||(!(int(b/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+xA-1051523;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x20000)*0x8000)+int(((v&lt;0)?v+s :v)/0x20000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(d/i)%2)+((int(c/i)%2)||(!(int(a/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+x1-2054922799;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x800)*0x200000)+int(((v&lt;0)?v+s :v)/0x800)+c;	if(b&gt;n)b-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(c/i)%2)+((int(b/i)%2)||(!(int(d/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+x8+1873313359;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x4000000)*0x40)+int(((v&lt;0)?v+s :v)/0x4000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(b/i)%2)+((int(a/i)%2)||(!(int(c/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+xF-30611744;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x400000)*0x400)+int(((v&lt;0)?v+s :v)/0x400000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(a/i)%2)+((int(d/i)%2)||(!(int(b/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+x6-1560198380;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x20000)*0x8000)+int(((v&lt;0)?v+s :v)/0x20000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(d/i)%2)+((int(c/i)%2)||(!(int(a/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+xD+1309151649;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x800)*0x200000)+int(((v&lt;0)?v+s :v)/0x800)+c;	if(b&gt;n)b-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(c/i)%2)+((int(b/i)%2)||(!(int(d/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=a+x4-145523070;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	a=((v%0x4000000)*0x40)+int(((v&lt;0)?v+s :v)/0x4000000)+b;	if(a&gt;n)a-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(b/i)%2)+((int(a/i)%2)||(!(int(c/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=d+xB-1120210379;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	d=((v%0x400000)*0x400)+int(((v&lt;0)?v+s :v)/0x400000)+a;	if(d&gt;n)d-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(a/i)%2)+((int(d/i)%2)||(!(int(b/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=c+x2+718787259;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	c=((v%0x20000)*0x8000)+int(((v&lt;0)?v+s :v)/0x20000)+d;	if(c&gt;n)c-=s;
v=0;for(i=1;i&lt;s;i*=2){v+=(((int(d/i)%2)+((int(c/i)%2)||(!(int(a/i)%2))))%2)*i;}if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	v+=b+x9-343485551;	if(v&lt;0){v+=s;}else if(v&gt;n){v-=s};	b=((v%0x800)*0x200000)+int(((v&lt;0)?v+s :v)/0x800)+c;	if(b&gt;n)b-=s;

a += aa;if(a&lt;0){a+=s;}else if(a&gt;n){a-=s};
b += bb;if(b&lt;0){b+=s;}else if(b&gt;n){b-=s};
c += cc;if(c&lt;0){c+=s;}else if(c&gt;n){c-=s};
d += dd;if(d&lt;0){d+=s;}else if(d&gt;n){d-=s};</pre>
<pre>

//md5Hex.as

if(p&lt;length(blocks)){
	gotoAndPlay(_currentframe-1)
}else{
	hex = ''
	for(i = 1; i &lt;s ; i *= 0x100 ) {
		hex = hex add subString('0123456789abcdef',(int(a/(i*0x10))%0x10)+1,1)
		hex = hex add subString('0123456789abcdef',(int(a/i)%0x10)+1,1)
	}
	for(i = 1; i &lt;s ; i *= 0x100 ) {
		hex = hex add subString('0123456789abcdef',(int(b/(i*0x10))%0x10)+1,1)
		hex = hex add subString('0123456789abcdef',(int(b/i)%0x10)+1,1)
	}
	for(i = 1; i &lt;s ; i *= 0x100 ) {
		hex = hex add subString('0123456789abcdef',(int(c/(i*0x10))%0x10)+1,1)
		hex = hex add subString('0123456789abcdef',(int(c/i)%0x10)+1,1)
	}
	for(i = 1; i &lt;s ; i *= 0x100 ) {
		hex = hex add subString('0123456789abcdef',(int(d/(i*0x10))%0x10)+1,1)
		hex = hex add subString('0123456789abcdef',(int(d/i)%0x10)+1,1)
	}
}

</pre>
</div>]]>
    </content>
</entry>
<entry>
    <title>PHP：Mixiアプリモバイルの RESTful API を RESTful に使う</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2009/10/phpmixi_apirequest.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=661" title="PHP：Mixiアプリモバイルの RESTful API を RESTful に使う" />
    <id>tag:faces.jp,2009://1.661</id>
    
    <published>2009-10-11T12:33:07Z</published>
    <updated>2009-10-11T18:02:03Z</updated>
    
    <summary>クラスを作ってみた。...</summary>
    <author>
        <name>ao</name>
        
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        クラスを作ってみた。
        <![CDATA[<style type=text/css>
<!--
div.ao p{line-height:24px;margin-bottom:18px;}
div.ao pre{padding:9px;font-size:12px;background:#FFFFDD;border:1px solid #87C300;margin-bottom:18px;}
-->
</style><div class="ao"><p>
Auth を気にすることなくサクサク書けます。
</p>
<pre>

require_once('MixiAppMobileApi.php');

// APIのURLなどの詳細は以下を参照。
// http://developer.mixi.co.jp/appli/appli_mobile/lets_enjoy_making_mixiappmobile/for_partners

$personApi		= 'http://****************************************';
$persistenceApi	= 'http://****************************************';


$mixi = new MixiAppMobileApi;

// owner(viewer) データ取得
print_r($mixi->get($personApi));

// appData 追加
$mixi->post(
	$persistenceApi,
	array(
		'score'	=> 530000,
		'time'	=> time(),
	)
);

// appData から score を削除
$mixi->delete($persistenceApi.'?fields=score');

// appData 取得
$myAppData = $mixi->get($persistenceApi);
print_r($myAppData);

</pre>
<p>3つのメソッドにURLをそえるだけ。なんて RESTful なんでしょう。<br />
<br />
さておき、複数のアプリとか複数の環境で開発したりしていて、<br />
Consumer を逐一書き換えるのが手間な場合は、以下のクラスメソッドを使えばOKです。</p>
<pre>
MixiAppMobileApi::initWithConsumer(
	'********************',//key
	'****************************************'//secret
);

$mixi = new MixiAppMobileApi;
print_r($mixi->get($personApi));
</pre>
<p>
以下ソース MixiAppMobileApi.php<br />
※ OAuth のライブラリが必要です。
</p>
<pre>
&lt;?

require_once('OAuth.php');

class MixiAppMobileApi{
	
	static	$consumer;	
	static	$consumerKey	= '';//設定して下さい
	static	$consumerSecret	= '';//設定して下さい
	static	$appId		= '';
	static	$ownerId	= '';
	
	var 	$rawData;
	
		public static function initWithConsumer($key,$secret){
		self::$consumerKey		= $key;
		self::$consumerSecret	= $secret;
		self::init();
	}
	
	static function init(){
	
		if(isset($_GET['opensocial_app_id'])){
			self::$appId	= $_GET['opensocial_app_id'];
		}
		
		if(isset($_GET['opensocial_owner_id'])){
			self::$ownerId	= $_GET['opensocial_owner_id'];
		}
		
		self::$consumer	= new OAuthConsumer(
			self::$consumerKey,
			self::$consumerSecret,
			null
		);
		
	}
	
	function MixiAppMobileApi(){
		if(!isset(self::$consumer)){self::init();}
	}
	
	public function get($url)		{ return( $this-&gt;request($url) );		}
	public function post($url,$data)	{ return( $this-&gt;request($url,$data) );		}
	public function delete($url)		{ return( $this-&gt;request($url,null,'DELETE') );	}
	
	function request($url,$data=null,$method=null){
		
		switch(true){
			case(isset($data)):
				$options	= array('method' =&gt; 'POST', 'content' =&gt; json_encode($data));
				break;

			case(empty($method)):
				$options	= array('method' =&gt; 'GET');
				break;

			default:
				$options	= array('method' =&gt; $method);

		}
		
		list($baseFeed,$queryString)	= explode('?', $url, 2);
		
		$parameters		= $this-&gt;parameters($queryString);
		$options['header']	= $this-&gt;header(
			OAuthRequest::from_consumer_and_token(
				self::$consumer,
				null,
				$options['method'],
				$baseFeed,
				$parameters
			)
		);
		
		$this-&gt;rawData	= file_get_contents(
			$baseFeed . '?' . http_build_query($parameters,'','&'),
			null,
			stream_context_create(array('http' =&gt; $options))
		);

		return(json_decode($this-&gt;rawData));
		
	}
	
	function parameters($queryString=null){
		$parameters	= array(
			'xoauth_requestor_id' =&gt; self::$ownerId,
		);
		if(isset($queryString)){
			parse_str($queryString,$q);
			$parameters += $q;
		}
		return($parameters);
	}
		
	function header($request){
		$request-&gt;sign_request(
			new OAuthSignatureMethod_HMAC_SHA1(),
			self::$consumer,
			null
		);
		$rows = array(
			'Content-Type: application/json',
			$request-&gt;to_header(),
			'',
		);
		return(implode("\r\n",$rows));
	}
	
	function id($string){
		list($null,$id) = explode(':',$string);
		return($id);
	}
}
</pre>
</div>]]>
    </content>
</entry>
<entry>
    <title>flashでmp3をzipで固めたのを読みこんで再生</title>
    <link rel="alternate" type="text/html" href="http://faces.jp/2009/10/flashmp3zip.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://faces2.bascule.co.jp/mt/mt-atom.cgi/weblog/blog_id=1/entry_id=660" title="flashでmp3をzipで固めたのを読みこんで再生" />
    <id>tag:faces.jp,2009://1.660</id>
    
    <published>2009-10-04T20:51:43Z</published>
    <updated>2009-10-04T21:43:22Z</updated>
    
    <summary>SE系の、小さなMP3ファイルをたくさん読みこむ時は、zipにまとめたほうがスマ...</summary>
    <author>
        <name>kamp</name>
        <uri>/2006/08/kampprofile.html</uri>
    </author>
            <category term="article" />
    
    <content type="html" xml:lang="ja" xml:base="http://faces.jp/">
        SE系の、小さなMP3ファイルをたくさん読みこむ時は、zipにまとめたほうがスマートかな、と思い、やってみました。
        <![CDATA[<div id="zip_mp3_div"></div>
<script type="text/javascript">
new SWFObject("/files/kampei/zip_mp3/zip_mp3.swf", "boid", 400, 600, 9, "#000000").write("zip_mp3_div");
</script>
<br>
zipを動的に読み込み、zip内のmp3ファイルをリストアップし、Soundクラスとして扱えるようにします。

リストをクリックすると、音が出ます。

<br>

Flash内でのzip解凍は、<a href="http://codeazur.com.br/lab/fzip/" target="_blank">FZip</a>というライブラリを使ってます。

このライブラリは、普通のzipファイルは読み込めず、Alder32っていうchecksumを足す必要があるようです。僕もよく分かってないのですが、FZipのサイトにPythonのスクリプトが落ちてるので、無心にそれを実行するとよいです。
<br>

音源は、SLNさんの公開している、<a href="http://blog.slndesignstudio.com/archives/2008/10/general_audio_service_01.html" target="_blank">General Audio Service</a>でダウンロードできる<a href="http://yasuhirotsuchiya.com/archives/sln_gas_01_mp3.zip">mp3をzipで固めたもの</a>を、読み込んでます。
<br>

また、zipから取り出したmp3をいったんByteArrayに取り込んで、Soundクラスとして生成し直すまでのプロセスは、<a href="http://www.flexiblefactory.co.uk/flexible/?p=46" target="_blank">MP3FileReferenceLoaderLib</a>を使わせてもらいました。これはバイナリを何かゴニョゴニョしていていて、神すぎて全く分からないのですが、FilreReferenceからmp3を読み込むようになってたのを、zip経由で読み込むようにしたり、メモリを使いすぎないようにしたりしていたら、いろいろ変わってしまったので、畏れ多くも、com.kampei以下に入れときました。
(そういう自由なライセンスだと読めたんだけど、どうだろう...)<br>


やってみたのはいいのですが、思った以上にメモリを食い、実用性を疑っています。
普通にMP3を読み込んだ方がメモリ負荷は軽いのかな？？？
<br>

<a href="/files/kampei/zip_mp3/zip_mp3_src.zip">ソース</a>です。Pythonのスクリプトとかも、モロモロ入ってます。もはやライブラリの組み合わせでしかないけど...


]]>
    </content>
</entry>

</feed> 


