イラストレーターに貼り付けた画像をパスを元に分割する:CropPlacedItem

さてさて、これは何の写真か判りますか?

これは元々1枚の車の写真をバラバラにしたものです。
なんて、くだらないクイズはさておき。
1枚の画像をこれだけバラバラにするのは結構めんどくさいですよね?
ということでスクリプトを書いてみました。
画像上のパス情報を元に画像を切り抜くスクリプト

こんな風にバラバラになります。

何をやってるかというと、パス情報を元にBridgeTalkを使って
Photoshopで画像を切り抜いて別名保存して、
その切り抜いた画像をパスの位置に貼り付けます。
細かいエラー処理とかしてないのでお家使い用です。
動作はOSX上のCS3で行っています。動かなかったらあしからず。

#include 'c.js';//http://svn.coderepos.org//share/platform/illustrator/javascript/lib/c.js
#include 'matrixConvert.js';//http://d.hatena.ne.jp/kamiseto/20090502/1241251512

(function(){
//
var i = 0;
//
if(c('S').f('PL').length > 1 )return false;
var PI =  c('S').f('PL')[0];
var PI_MATRIX = matrixConvert.getAll(PI);
//
if(c('S').f('P').length < 1)return false;

c('S').f('P').each(function(){	
	//画像を開く
	toOpen(PI.file,'photoshop');
	
	//画像を切り抜いて保存
	var x1 = (this.left-PI.left);
	var y1 = (PI.top-this.top);
	var x2 = (this.width+x1);
	var y2 = (this.height+y1);
	
	//保存するファイル名
	var f = (PI.file.path+'/CROP_'+(i++)+'_'+PI.file.toString().replace (PI.file.path+'/', "")).replace(/(jpeg|jpg|eps|tiff)$/,'psd');
	toMakePath([
				x1/PI.width,
				y1/PI.height,
				x2/PI.width,
				y2/PI.height]
				,f);
	
	
	
	//画像が出来るまで待つ
	var timeout = 10*1000; //
	while(!File(f).exists && timeout > 0){
	               $.sleep (1000);
	               timeout = timeout-1000;
	}
	
	if(timeout > 0){
    	//画像の配置
    	var pA = app.activeDocument.placedItems.add();
    	pA.file = File(f);
    	//pA.matrix = PI.matrix;
    	pA.resize(PI_MATRIX.vs,PI_MATRIX.hs);
    	pA.position = this.position;
    	pA.moveBefore(this);
	}else{
	   return false;
	}
 	});

PI.remove();
})();



function toOpen(file,app){
var bt=new BridgeTalk();
bt.target = app;
bt.body ="open (File('"+file+"'));";
bt.send();
}

function toMakePath(ract,f){
var script = "function MakeRactangle(data){\r"+
"var ract = [];\r"+
"ract[0] = new SubPathInfo();\r"+
"ract[0].operation = ShapeOperation.SHAPEADD;\r"+
"ract[0].closed = true;\r"+
"ract[0].entireSubPath = [\r"+
"MakepathData(data[0],data[1]),\r"+
"MakepathData(data[0],data[3]),\r"+
"MakepathData(data[2],data[3]),\r"+
"MakepathData(data[2],data[1])\r"+
"];\r"+
"return ract;\r"+
"}\r"+

"function MakepathData(x,y){\r"+
"var pd = new PathPointInfo();\r"+
"with(pd){\r"+
"		kind = PointKind.CORNERPOINT;\r"+
"		anchor=  [x, y];\r"+
"		leftDirection=  [x, y];\r"+
"		rightDirection =  [x, y];\r"+
"}\r"+
"return pd;\r"+
"}\r"+
"docObj = activeDocument;\r"+
"var saveF = new File('"+f+"');\r"+
"docHeight = docObj.height.toString().match(/[0-9.]+/);\r"+
"docWidth = docObj.width.toString().match(/[0-9.]+/);\r"+
"dw_pix=(docWidth/25.4*72);\r"+
"dh_pix=(docHeight/25.4*72);\r"+
"pObj = docObj.pathItems.add('made in javascript', MakeRactangle(["+(ract[0])+"*dw_pix,"+(ract[1])+"*dh_pix,"+(ract[2])+"*dw_pix,"+(ract[3])+"*dh_pix]));\r"+
"var pp = pObj.subPathItems[0].pathPoints;\r"+
"var xp = [];\r"+
"var yp = [];\r"+
"var sortOpt = function(a,b){return a-b}\r"+
"for(i=0;i<pp.length;i++){\r"+
"	xp.push(pp[i].anchor[0]);\r"+
"	yp.push(pp[i].anchor[1]);\r"+
"}\r"+
"xp.sort(sortOpt);\r"+
"yp.sort(sortOpt);\r"+
"var pWidth = xp[xp.length-1] - xp[0];\r"+
"var pHeight = yp[yp.length-1] - yp [0];\r"+
"pObj.makeSelection(0,false);\r"+
"pObj.remove();\r"+
"app.activeDocument.selection.copy();\r"+
"app.documents.add(UnitValue(pWidth,'pt'),UnitValue(pHeight,'pt'),docObj.resolution,'',getNewDocumentMode(),DocumentFill.TRANSPARENT,1,docObj.bitsPerChannel);\r"+
"app.activeDocument.paste();\r"+
"docObj.close(SaveOptions.DONOTSAVECHANGES);\r"+
"app.activeDocument.saveAs(saveF);\r"+
"app.activeDocument.close();\r"+
"saveF;\r"+
"function getNewDocumentMode(){\r"+
"switch(docObj.mode.toString().match(/DocumentMode.(.+)$/)[1]){\r"+
"		case 'CMYK' : return NewDocumentMode.CMYK;\r"+
"		case 'RGB' : return NewDocumentMode.RGB;\r"+
"		case 'GRAYSCALE' : return NewDocumentMode.GRAYSCALE;\r"+
"		default : return NewDocumentMode.RGB;\r"+
"}\r"+
"}\r"
try{
    var bt=new BridgeTalk();
    bt.target = 'photoshop';
    bt.body = script;
    bt.onError = BridgeTalkErrorHandler;
    bt.onResult = function(res) {
            resF = res.body;
             }
    bt.send();
}catch(e){
    throw(e);
}
}

function BridgeTalkErrorHandler (btObj) {alert( btObj.body + " (" + btObj.headers ["Error-Code"] + ")" ); }

BridgeTalkはデバックしにくくてとっても疲れました。
最初、BridgeTalkで処理を投げたらそのままスクリプトが流れてしまい
切り抜き画像が出来る前に配置処理までいってしまうのでエラーが出てしまいました。
File(filepath).existsでファイルが出来てくるまでwhileでループさせることで解決しました。
画像が出来るまで待たせる処理がなかな思いつかなくて苦労しました。