Fireworksでレイヤー内のオブジェクトをひとつひとつPNGに書き出す自動処理(JSF)
Flash制作時にFireworksからレイヤーごとに素材を切り出すことがありますが、その際に、各レイヤーをON/OFFで切り替えて画像として切り出すので、大量にあると大変です。
そこで、Fireworksでレイヤー内のオブジェクトをひとつひとつPNGに書き出す自動処理(JSF)ができたので、以下にメモしておきます。
動作イメージ
動作は、sample.fw.pngにJSFを実行すると_baseフォルダにレイヤー内のオブジェクトがPNGとして書きだされます。
図で書くと以下のとおり。
各オブジェクトにしっかり名前を付けて、見渡してから一つ一つファイルを書き出すことができます。
実際のJSF
jsf_layer_to_png.jsf
function Main(){
this.init.apply(this, arguments);
}
Main.prototype.init = function(){
this.section( fw.getDocumentDOM() );
}
Main.prototype.section = function( doc ){
// ドキュメントの各情報を取得
this.DocInfo = new DocInfo( doc );
// ・fileFullName ファイル名取得
// ・fileName 拡張子をなくしたファイル名を取得
// ・extension 拡張子を取得
// ・fileFullPath ファイルのパス
// ・folderPath フォルダのパス
// 書き出し設定
// colorMode:"32 bit"・exportFormat:"PNG"でPNG32出力。
var setting = {
animAutoCrop:true, animAutoDifference:true, applyScale:false,
colorMode:"32 bit",
crop:false, cropBottom:0, cropLeft:0, cropRight:0, cropTop:0, ditherMode:"none", ditherPercent:100,
exportFormat:"PNG", frameInfo:[ ],
interlacedGIF:false,
jpegQuality:80, jpegSelPreserveButtons:false, jpegSelPreserveText:true, jpegSelQuality:90, jpegSelQualityEnabled:false,
jpegSmoothness:0, jpegSubsampling:0, localAdaptive:true, lossyGifAmount:0,
macCreator:"????", macFileType:"????", name:null,
numCustomEntries:0, numEntriesRequested:0, numGridEntries:6, optimized:true,
paletteEntries:null, paletteInfo:null, paletteMode:"adaptive", paletteTransparency:"index alpha",
percentScale:100, progressiveJPEG:false, savedAnimationRepeat:0, sorting:"none", useScale:true,
webSnapAdaptive:false, webSnapTolerance:14,
xSize:0, ySize:0
}
// 書き出すべきオブジェクトを取得
var parts = this.getParts( doc );
// _baseというフォルダに書きだすのでフォルダを作っておく
Files.createDirectory( this.DocInfo.folderPath + "_base" )
// オブジェクトを1つずつ処理
for( var i = 0; i < parts.length ; i++ ){
// 全レイヤーを非表示にする
this.hiddenLayer( doc );
// 今回のエレメント
var part = parts[ i ];
// デフォルトの名前から変更したものはpart.nameがnullではなくなるので
// 書き出しの対象とする
if( part.name != null ){
part.visible = true;
doc.setExportOptions( setting );
// this.DocInfo.folderPathを使ってフォルダのパスを基準に
// _baseというフォルダに書き出します
fw.exportDocumentAs( doc, this.DocInfo.folderPath + "_base/" + part.name + ".png" , null );
}
}
}
// 書き出すべきオブジェクトを取得
Main.prototype.getParts = function( doc ){
var ret = [];
var layers = doc.layers;
for( var i = 0; i < layers.length ; i++ ){
var layer = layers[i];
for( var j = 0; j < layer.elems.length ; j++ ){
var part = layer.elems[ j ];
if( part.name != null ){
ret.push( part );
}
}
}
return ret;
}
// 全レイヤーを非表示にする
Main.prototype.hiddenLayer = function( doc ){
var layers = doc.layers;
for( var i = 0; i < layers.length ; i++ ){
var layer = layers[i];
for( var j = 0; j < layer.elems.length ; j++ ){
var part = layer.elems[ j ];
part.visible = false;
}
}
}
// DocInfo
function DocInfo( doc ){
// ファイル名取得
this.fileFullName = doc.filePathForSave.split("/").pop();
// 拡張子をなくしたファイル名を取得
this.fileName = this.fileFullName.split(".")[0];
// 拡張子を取得
this.extension = this.fileFullName.split(".")[1];
// ファイルのパス
this.fileFullPath = doc.filePathForSave;
// フォルダのパス
this.folderPath = this.fileFullPath.substr( 0 , this.fileFullPath.length - this.fileFullName.length );
}
// _________ 処理開始
// try catchを利用することで、最低限のエラーを表示できるようにしています。
// これで検出できないエラーは多数あります。
try{
var main = new Main();
} catch( e ){
confirm( "[ERROR]" + e );
}
自分の操作したかったのは厳密にはレイヤーではなくオブジェクト
作っていくにつれて、自分の操作したかったのは、JSFにおいて、厳密にはレイヤー(doc.layers)ではなくオブジェクト(doc.layers.elem)ということが分かりました。当初、上手く呼び出せず、ちょっとハマりました。
図で書くと以下の感じ。
layersが示しているのはレイヤーフォルダで、leyers[0].elemsがその中のオブジェクトということです。
良かったところ
さて、今回のJSFを使ってよかったこととしては、
- 書き出し前にレイヤー名で検討できるので、全体的に命名を設計しやすくなった。
- 仮に途中で命名変えたくなったときは簡単に修正できる。
- 書き出しの時の保存ダイアログを行き来する必要がなくなり作業がシンプルになった。
- 保存ダイアログのときにファイル名を考えているとフローが煩雑になりやすい
- 些細なオペレーションミスが解消できた。
- 例えば、目的のレイヤーとファイル名がズレてしまうようなミス
- 例えば、連番をつけていたはずなのに、うっかり飛ばしてしまったりするミス
- 数個ならいいが、大量にやるときはどうしてもミスが生じやすい。
というのがありました。
おわりに
いかがでしたでしょうか。
もちろんひとつひとつ丁寧に手作業でやれる時は良いのですが、短期間に大量にミスなく行いたいときは効果を発揮しそうです。
今回のソースコードも、以下においておきます。
データダウンロード:jsf_layer_to_png.zip
それでは、よきFireworks JSF Lifeを!

