画像サイズを自動取得するJSXからmixin作成まで



## PhotoShopからCSVを出力するJSX

`/Applications/Adobe Photoshop CC 2018/Presets/Scripts`
Mac環境でこちらのディレクトリにjsxファイルを置く
フォトショのバージョンは適宜変更

[PhotoshopのGenerator機能で出力されたレイヤーおよびレイヤーセットの位置情報をリストアップするJSXを作りました](https://www.1ft-seabass.jp/memo/2015/01/16/generator_png_layer_listup_jsx/)
今回、使用させてもらったスクリプト

`.png`と名前を付けたレイヤーの名前、位置、サイズを取得する。


```javascript:generator_png_layer_listup.jsx
/**
 * generator_png_layer_listup.jsx
 */
 
// 処理に該当する拡張子名の配列
// 今回は png のみなので .png
var extensions = [".png"];
// 書き出す際のテキストを貯める変数
var strData = "";
 
// 以下処理 ///////////////////////////////////////////////////////
if( app.documents.length == 0 ){
    alert( "【！】実行するドキュメントがありません。" );
} else {
    main();
}
 
function main(){
    if(confirm( activeDocument.name + "から、pngのつくレイヤーから矩形抽出しますか？" )){
        section();
    }
    alert( "すべての処理が完了しました。お疲れ様でした。" );
    return "完了";
}
 
function section(){
 
    // ファイルを作成し、テキストレイヤー書き出し処理へ
    var fileName = activeDocument.fullName + "_export.csv";
    var file = new File(fileName);
    var openFlag = file.open("w");
 
    if(openFlag) {
        // 再帰的に処理
        allLayerSetsBounds( activeDocument );
        // CSVテキストの出力
        file.write(strData);
        file.close();
        // 完了
        alert("書き出しが完了しました。");
    } else {
        alert("ファイルが開けませんでした。");
    }
}
 
// レイヤー名に処理に該当する拡張子が含まれているか捜索する
function checkNameExtensions( name ) {
    var len = extensions.length;
    var ret = false;
    for (var i=0; i<len; i++){
        var checkName = extensions[i];
        if( name.indexOf(checkName) > -1 ){
            ret = true;
        }
    }
    return ret;
}
 
function getGeneratedLayersName( artLayers ) {
    var ret = [];
    var ns = artLayers.length;
    for (var i=0; i<ns; i++){
        var focusLayer = artLayers[i];
        if( checkNameExtensions( focusLayer.name ) ){
            ret.push( focusLayer.name );
        }
    }
    return ret;
}
 
function allLayerSetsBounds( layObj ){
    var n = layObj.artLayers.length;
 
    // レイヤーフォルダ内のレイヤー捜索 ////////////////////////////////////////
 
    // レイヤー名に処理に該当する拡張子が含まれているか捜索する
    var lList = getGeneratedLayersName(layObj.artLayers);
    // あれば1つ1つ捜索しテキスト生成しCSV用テキストへ連結
    var n = lList.length;
    if( n > 0 ) {
        $.writeln ( "[" + lList + "]" );
        for (var i = 0; i < n; i++) {
            var lname = lList[i];
            var focusLayer = layObj.artLayers.getByName(lname);
 
            var focusLayerArea = focusLayer.bounds;  // フォーカスエリアを取得
            var x1 = parseInt(focusLayerArea[0]);  // 左上 x座標
            var y1 = parseInt(focusLayerArea[1]);  // 左上 y座標
 
            var addStr = focusLayer.name + "," + x1 + "," + y1;  // テキスト生成
 
            // デバック出力
            $.writeln(addStr);
 
            strData += addStr + "\n";  // CSV用テキストへ連結
        }
    }
 
    // 配下のレイヤーフォルダを捜索
    var ns = layObj.layerSets.length;
    for (var i=0; i<ns; i++){
        var focusLayerSet = layObj.layerSets[i];
 
        // デバック出力
        $.writeln ( "[" + focusLayerSet.name + "]" );
 
        // レイヤーセット名に該当する拡張子を捜索する
        if( checkNameExtensions( focusLayerSet.name ) ){
 
            var focusLayerSetArea = focusLayerSet.bounds;  // フォーカスエリアを取得
            var x1 = parseInt(focusLayerSetArea[0]);  // 左上 x座標
            var y1 = parseInt(focusLayerSetArea[1]);  // 左上 y座標
            var x2 = parseInt(focusLayerSetArea[2]);
            var y2 = parseInt(focusLayerSetArea[3]);
 
            var addStr = focusLayerSet.name + "," + x1 + "," + y1 + "," + (x2 - x1) + "," + (y2 - y1);  // テキスト生成

            // デバック出力
            $.writeln ( "    " + addStr );
 
            strData += addStr + "\n";  // CSV用テキストへ連結
        }
        // 再帰的に処理
        allLayerSetsBounds( focusLayerSet );
    }
}
```

一部、画像の縦横サイズを取得するために以下のコードに修正

```javascript
var x1 = parseInt(focusLayerSetArea[0]);  // 左上 x座標
var y1 = parseInt(focusLayerSetArea[1]);  // 左上 y座標
var x2 = parseInt(focusLayerSetArea[2]);
var y2 = parseInt(focusLayerSetArea[3]);

var addStr = focusLayerSet.name + "," + x1 + "," + y1 + "," + (x2 - x1) + "," + (y2 - y1);  // テキスト生成
```


## CSVからSassの変数を生成

`package.json`のscriptsフィールドに、
CSVからSassの変数を生成するgulpタスクを登録する。

```json:package.json
"image-var": "gulp csv2sass-var"
```

```javascript:gulpfile.babel.js
import gulp from 'gulp';
import fs from 'fs';
import csvSync from 'csv-parse/lib/sync';

gulp.task('csv2sass-var', (done) => {
    const inputFile = `image.csv`;
    const outputFile = `${SRC}/scss/variable/_images.scss`;
    const data = fs.readFileSync(inputFile);
    const res = csvSync(data);
    let outputStr = '';
    res.forEach(elm => {
        const title = elm[0].replace('.png', '');
        if(title){
            // 名前と横縦のサイズを登録
            outputStr += `$image-${title}: "${elm[0]}" ${elm[3]} ${elm[4]}` + `;\n`;
        }
    });
    fs.writeFileSync(outputFile, outputStr);
    done();
})
```

`npm run image-var`で実行する

```scss:variable/_image.scss
$image-fv-ballon: "fv-ballon.png" 600 300;
$image-fv-title: "fv-title.png" 800 450;
・
・
・
```


## mixinで使用する

```scss:mixin/_image.scss
@mixin image($image, $scale:1){
    background-image: url("../img/" + nth($image, 1));
    $width: ceil( nth($image, 2) * $scale ) + px;
    $height: ceil( nth($image, 3) * $scale ) + px;
    background-size: $width $height;
    width: $width;
    height: $height;
}
```

```scss:使用
@include image($image-fv-title,0.5);
```



> 参考
[Photoshop CS自動化作戦](http://www.openspc2.org/book/PhotoshopCS/)
[JavaScriptでPhotoshopを自動化してみよう！基礎編①](http://www.go-next.co.jp/blog/web/photoshop/13019/)