2010-09-01

利用 PhotoShop 製作 CSS Sprite

原本想用 PhotoShop 的巨集來製作 CSS Sprite 的圖片,但沒想到巨集沒辦法很方便的匯入圖片到圖層上,最後找到一個可行的方法就是寫 PhotoShop 的 Script。

我只有兩個需求:
  • 處理圖檔組合
  • 紀錄每張圖的起始定位
雖然已經寫完了,但是還是有一些小小的 Bug,對於透明底色的 png 會有定位上的偏差,我的解決辦法就是在四個角畫上 1px 透明為 1% 的白色,雖然美中不足但勉強夠用。
這個小 Bug 已經解決了。


這個 Script 的執行方式很簡單
只要將需要合併的圖檔全部開啟
接著『檔案 -> 指令碼 -> 瀏覽』選擇下載後的 css_sprite_ps-script.jsx
執行後會建立一個新圖檔,並且要選擇輸出的 CSS 的檔案名稱


// css_sprite_ps-script.jsx
#target photoshop

/** 建立參考線
* @param {Int} pixelOffSet 偏移像素
* @param {String} orientation ["Vrtc" => 垂直 ,"Hrzn" => 水平]
*/
function makeGuide(pixelOffSet, orientation) {
var id8 = charIDToTypeID( "Mk " );
var desc4 = new ActionDescriptor();
var id9 = charIDToTypeID( "Nw " );
var desc5 = new ActionDescriptor();
var id10 = charIDToTypeID( "Pstn" );
var id11 = charIDToTypeID( "#Rlt" );
desc5.putUnitDouble( id10, id11, pixelOffSet ); // integer
var id12 = charIDToTypeID( "Ornt" );
var id13 = charIDToTypeID( "Ornt" );
var id14 = charIDToTypeID( orientation ); // "Vrtc", "Hrzn"
desc5.putEnumerated( id12, id13, id14 );
var id15 = charIDToTypeID( "Gd " );
desc4.putObject( id9, id15, desc5 );
executeAction( id8, desc4, DialogModes.NO );
}

function main(){
//判斷是否有開啟圖檔
if (app.documents.length = 0) {return;}

//設定前景色為白色
app.foregroundColor.rgb.hexValue = 'FFFFFF';

var atDoc;
var list = [];
var length = app.documents.length;

//新增目標圖片文件
var newPic = app.documents.add(
1, 1, 72,
"css_sprite",
NewDocumentMode.RGB,
DocumentFill.TRANSPARENT
);

var height=0;
var width = newPic.width;
//複製所有圖檔至新建立的圖檔
for (var i=0; i<length; i++){
atDoc=app.activeDocument=app.documents[i];

//記錄圖層資訊
var newLayer={
name: atDoc.name, //檔名
width: atDoc.width,
height: atDoc.height,
top: height
};

//累計高度
height += app.documents[i].height.value;
//最大寬度
if(width < atDoc.width){ width=atDoc.width;}

//新增圖層
var aLayer = atDoc.activeLayer=atDoc.artLayers.add();

//複製背景底圖
try {
atDoc.backgroundLayer.duplicate(aLayer,ElementPlacement.PLACEAFTER);
atDoc.backgroundLayer.remove();
} catch (e){}

//將新圖層與下一層互換
aLayer.move(atDoc.layers[1],ElementPlacement.PLACEAFTER);

//標註四周的定位點
var w=atDoc.width.value, h=atDoc.height.value;
atDoc.selection.select([[0,0],[1,0],[1,1],[0,1],[0,0]]);
atDoc.selection.fill(app.foregroundColor)
atDoc.selection.select([[0,h-1],[0,h],[1,h],[1,h-1],[0,h-1]]);
atDoc.selection.fill(app.foregroundColor)
atDoc.selection.select([[w-1,0],[w-1,1],[w,1],[w,0],[w-1,0]]);
atDoc.selection.fill(app.foregroundColor)
atDoc.selection.select([[w-1,h-1],[w-1,h],[w,h],[w,h-1],[w-1,h-1]]);
atDoc.selection.fill(app.foregroundColor)

//設定透明度
aLayer.fillOpacity=1;
//合併可見圖層
atDoc.mergeVisibleLayers();
//複製圖層
atDoc.selection.selectAll()
atDoc.selection.copy()

//貼上圖層
atDoc=app.activeDocument=newPic;
newLayer.obj = atDoc.paste();
list.push(newLayer);
};

//變更圖片大小
atDoc=app.activeDocument=newPic;
atDoc.resizeCanvas(width,height,AnchorPosition.TOPLEFT);

//變更圖層定位
for (var i=length-1; i>=0; i--){
//關閉複製過的檔案
app.documents[i].close(SaveOptions.DONOTSAVECHANGES);

//移動圖層
list[i].obj.translate(0,list[i].top);

//建立參考線
if(i>0){ makeGuide(list[i].top,"Hrzn"); }
};

// 輸出 CSS 定位檔
var mySavefile = File.saveDialog("輸出 CSS 定位檔","*.css");
if(!mySavefile){return};
if(mySavefile.exists && !confirm("你確定要覆蓋這個檔案?")){
return false;
}
// 開啟檔案
var fileRef = new File(mySavefile);
if (!fileRef.open("w","","")){
alert("無法開啟檔案!!");
fileRef.close();
return false;
}

// 輸出 CSS 定位設定
for (var i=0; i<list.length; i++){
fileRef.writeln(
list[i].name+'{ background-position: 0 -'+list[i].top+'px; }'
);
};
fileRef.close();
}


//把Photoshop推到最上層
app.bringToFront();
//設定使用的單位為「像素(Pixel)」
app.preferences.rulerUnits = Units.PIXELS;

main();


檔案下載:css_sprite_ps-script.jsx


有對這個興趣的朋友可以參考 PhotoShop 安裝目錄下的 "JavaScript Reference Guide.pdf" 的開發文件,雖然裡面全部都是英文的但還不置於看不懂。

0 回應: