2010-09-12 02:12

用 PhotoShop JSX 製作 CSS Sprite 的使用方法

自從上一篇 利用 PhotoShop 製作 CSS Sprite 發佈後我又改了 JSX 好幾次,現在終於修到讓我自己滿意了,順便來寫一下使用方法。

由於我的 PhotoShop 是 CS2 的,太舊的版本可能會沒有 Script 的功能,在這裡先聲明一下。

檔案連結:css_sprite_ps-script.jsx


  1. 先將所有需要組合的圖檔開啟


  2. 選擇『檔案 -> 指令碼 -> 瀏覽』


  3. 選擇下載後的 css_sprite_ps-script.jsx


  4. 接著馬上會要你選擇一個要參考的原始 CSS,這裡會解析你原本的樣式名稱跟檔案對應,當然不選也沒關係。
    解析 CSS 是用正規表示式去解析的,可能要花一點時間,我餵了一個兩千行的 CSS file 都還可以正常執行,再多我就不敢保證了。


  5. 我原始的 CSS 看起來像是這樣,當然稍微複雜一點內容應該也沒問題。


  6. 在圖片處理完後,會要選擇一個輸出定位的 CSS file


  7. 輸出的內容看起來會像是這樣


  8. 最後再將製作完成的圖檔存成自己需要的格式就可以了
2010-09-03 03:28

用 Eclipse CDT 編譯 CppSQLite3

工作上為了讓 sqlite 可以在 platform 上執行,所以必須從完整的 source code 開始編譯,對於不怎麼熟悉 Makefile 的我這真是一件麻煩的事,還好以前有玩過 CDT,索性就利用他可以自動建立 Makefile 的功能來做。

不過我是使用 Eclipse 3.2 版的 CDT,Eclipse 3.5 的 CDT 裡的 Makefile 我不太會用,也沒有時間去找文章。


這裡我下載了兩個檔案:
SQLite -> sqlite-source-3_7_2.zip
CppSQLite -> CppSQLite_3_1_demo_and_src.zip


首先建立動態連結庫
  1. 新增 "Managed Make C++ Project" 專案 -> 名稱 "cppsqlite"

  2. 在 Project Type 中選擇 Shared Library

  3. 在專案下新增 src 資料夾

  4. 複製 sqlite-source-3_7_2.zip 中所有的 source code 至 src 除了 shell.ctclsqlite.c

  5. 再複製 CppSQLite_3_1_demo_and_src.zip 中的 CppSQLite3.hCppSQLite3.cpp

  6. 開啟:專案 -> 內容

  7. 增加 Defined symbols 變數 -> SQLITE_CORE


  8. 在 C++ 跟 C 的 Optimization 的參數中增加 -fPIC 最佳化參數


  9. 按下『確定』後就會開始編譯,檔案有點多要稍微等一下



再來建立主程式專案
  1. 新增 "Managed Make C++ Project" 專案 -> 名稱 "sqlite-test"

  2. 在 Project Type 中選擇 Executable

  3. 在專案下新增 src 資料夾

  4. 複製 CppSQLite_3_1_demo_and_src.zip 中的 CppSQLite3Demo.cpp 至 src

  5. 開啟:專案 -> 內容

  6. 新增 Include paths -> "../../cppsqlite/src"
    這個設定是在告知編譯時額外 Include 的進來 Header(*.h) 的路徑。


  7. 新增連結路徑:
    Library search path -> "../../cppsqlite/Debug"
    Libraries -> cppsqlite
    這個設定是給 gcc 在做連結時需要的搜尋路徑,以及需要連結的對象名稱


  8. 按下『確定』後就會開始編譯

  9. 接著要將 cppsqlite.dll 複製到 sqlite-test/Debug 下
    Windows 的 lib 名稱為 "cppsqlite.dll"
    Linux 的 lib 名稱為 "libcppsqlite.so"

  10. 然後就可以執行 sqlite-test.exe 了 (一整個就很快樂)
專案範例:sqlite-test.zip
2010-09-01 23:50

利用 PhotoShop 製作 CSS Sprite

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

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


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

  1. // css_sprite_ps-script.jsx 
  2. #target photoshop 
  3.  
  4. /** 建立參考線 
  5. * @param {Int} pixelOffSet 偏移像素 
  6. * @param {String} orientation ["Vrtc" => 垂直 ,"Hrzn" => 水平] 
  7. */ 
  8. function makeGuide(pixelOffSet, orientation) { 
  9.    var id8 = charIDToTypeID( "Mk  " ); 
  10.    var desc4 = new ActionDescriptor(); 
  11.    var id9 = charIDToTypeID( "Nw  " ); 
  12.    var desc5 = new ActionDescriptor(); 
  13.    var id10 = charIDToTypeID( "Pstn" ); 
  14.    var id11 = charIDToTypeID( "#Rlt" ); 
  15.    desc5.putUnitDouble( id10, id11, pixelOffSet ); // integer 
  16.    var id12 = charIDToTypeID( "Ornt" ); 
  17.    var id13 = charIDToTypeID( "Ornt" ); 
  18.    var id14 = charIDToTypeID( orientation ); // "Vrtc", "Hrzn" 
  19.    desc5.putEnumerated( id12, id13, id14 ); 
  20.    var id15 = charIDToTypeID( "Gd  " ); 
  21.    desc4.putObject( id9, id15, desc5 ); 
  22.      executeAction( id8, desc4, DialogModes.NO ); 
  23. } 
  24.  
  25. function main(){ 
  26.    //判斷是否有開啟圖檔 
  27.    if (app.documents.length = 0) {return;} 
  28.  
  29.    //設定前景色為白色 
  30.    app.foregroundColor.rgb.hexValue = 'FFFFFF'; 
  31.  
  32.    var atDoc; 
  33.    var list = []; 
  34.    var length = app.documents.length; 
  35.  
  36.    //新增目標圖片文件 
  37.    var newPic = app.documents.add( 
  38.        1, 1, 72, 
  39.        "css_sprite", 
  40.        NewDocumentMode.RGB, 
  41.        DocumentFill.TRANSPARENT 
  42.    ); 
  43.  
  44.    var height=0; 
  45.    var width = newPic.width; 
  46.    //複製所有圖檔至新建立的圖檔 
  47.    for (var i=0; i<length; i++){ 
  48.        atDoc=app.activeDocument=app.documents[i]; 
  49.  
  50.        //記錄圖層資訊 
  51.        var newLayer={ 
  52.            name:   atDoc.name, //檔名 
  53.            width:  atDoc.width, 
  54.            height: atDoc.height, 
  55.            top:    height 
  56.        }; 
  57.  
  58.        //累計高度 
  59.        height += app.documents[i].height.value; 
  60.        //最大寬度 
  61.        if(width < atDoc.width){ width=atDoc.width;} 
  62.  
  63.        //新增圖層 
  64.        var aLayer = atDoc.activeLayer=atDoc.artLayers.add(); 
  65.  
  66.        //複製背景底圖 
  67.        try { 
  68.            atDoc.backgroundLayer.duplicate(aLayer,ElementPlacement.PLACEAFTER); 
  69.            atDoc.backgroundLayer.remove(); 
  70.        } catch (e){} 
  71.  
  72.        //將新圖層與下一層互換 
  73.        aLayer.move(atDoc.layers[1],ElementPlacement.PLACEAFTER); 
  74.  
  75.        //標註四周的定位點 
  76.        var w=atDoc.width.value, h=atDoc.height.value; 
  77.        atDoc.selection.select([[0,0],[1,0],[1,1],[0,1],[0,0]]); 
  78.        atDoc.selection.fill(app.foregroundColor) 
  79.        atDoc.selection.select([[0,h-1],[0,h],[1,h],[1,h-1],[0,h-1]]); 
  80.        atDoc.selection.fill(app.foregroundColor) 
  81.        atDoc.selection.select([[w-1,0],[w-1,1],[w,1],[w,0],[w-1,0]]); 
  82.        atDoc.selection.fill(app.foregroundColor) 
  83.        atDoc.selection.select([[w-1,h-1],[w-1,h],[w,h],[w,h-1],[w-1,h-1]]); 
  84.        atDoc.selection.fill(app.foregroundColor) 
  85.  
  86.        //設定透明度 
  87.        aLayer.fillOpacity=1; 
  88.        //合併可見圖層 
  89.        atDoc.mergeVisibleLayers(); 
  90.        //複製圖層 
  91.        atDoc.selection.selectAll() 
  92.        atDoc.selection.copy() 
  93.  
  94.        //貼上圖層 
  95.        atDoc=app.activeDocument=newPic; 
  96.        newLayer.obj = atDoc.paste(); 
  97.        list.push(newLayer); 
  98.    }; 
  99.  
  100.    //變更圖片大小 
  101.    atDoc=app.activeDocument=newPic; 
  102.    atDoc.resizeCanvas(width,height,AnchorPosition.TOPLEFT); 
  103.  
  104.    //變更圖層定位 
  105.    for (var i=length-1; i>=0; i--){ 
  106.        //關閉複製過的檔案 
  107.        app.documents[i].close(SaveOptions.DONOTSAVECHANGES); 
  108.  
  109.        //移動圖層 
  110.        list[i].obj.translate(0,list[i].top); 
  111.  
  112.        //建立參考線 
  113.        if(i>0){ makeGuide(list[i].top,"Hrzn"); } 
  114.    }; 
  115.  
  116.    // 輸出 CSS 定位檔 
  117.    var mySavefile = File.saveDialog("輸出 CSS 定位檔","*.css"); 
  118.    if(!mySavefile){return}; 
  119.    if(mySavefile.exists && !confirm("你確定要覆蓋這個檔案?")){ 
  120.        return false; 
  121.    } 
  122.    // 開啟檔案 
  123.    var fileRef = new File(mySavefile); 
  124.    if (!fileRef.open("w","","")){ 
  125.        alert("無法開啟檔案!!"); 
  126.        fileRef.close(); 
  127.        return false; 
  128.    } 
  129.  
  130.    // 輸出 CSS 定位設定 
  131.    for (var i=0; i<list.length; i++){ 
  132.        fileRef.writeln( 
  133.            list[i].name+'{ background-position: 0 -'+list[i].top+'px; }' 
  134.        ); 
  135.    }; 
  136.    fileRef.close(); 
  137. } 
  138.  
  139.  
  140. //把Photoshop推到最上層 
  141. app.bringToFront(); 
  142. //設定使用的單位為「像素(Pixel)」 
  143. app.preferences.rulerUnits = Units.PIXELS; 
  144.  
  145. main(); 


檔案下載:css_sprite_ps-script.jsx


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