メニュー
\ 最大8%ポイントアップ! /詳細を見る

【Photoshop】拡張機能でカスタムパネルを作成する方法[プラグイン]

eyecatch_ photoshop

Photoshopの拡張機能のカスタムパネルを試してみました。(※Photoshop CC 2014以降で作成可能です)

これで自作ツールを並べることができますし、htmlで構成されているのでcssでの見た目も調整できるので、かなりテンション上がります!

海外でフリーランスをしているテクニカルアーティスト
ゲーム開発・映像制作・WEB制作等を請け負っています。
当ブログは作業効率化のための技術ブログです。

目次

Photoshop拡張機能でカスタムパネルを表示する方法

まずは環境構築をしてしまいましょう!

[timeline]
[tl label=’STEP.1′ title=’Bracketsのインストール’]
下記のURLからAdobeが開発のテキストエディタをインストール
http://brackets.io/

[/tl]
[tl label=’STEP.2′ title=’>Creative Cloud Extension Builder for Bracketsのインストール’]
Bracketsを起動して、ファイル>拡張機能マネージャー>URLからインストールから下記のURLをコピペして、インストール

GitHub
GitHub - davidderaedt/CC-Extension-Builder-for-Brackets: A brackets Extension for building Creative ... A brackets Extension for building Creative Cloud extensions - davidderaedt/CC-Extension-Builder-for-Brackets

[/tl]
[tl label=’STEP.3′ title=’>サンプルの拡張機能を作成’]
メニューにCC Extension Builderが追加されるので、そこからNew Creative Cloud Extension>Create Extensionを実行

[/tl]
[tl label=’STEP.4′ title=’>バージョンの記述の変更’]

このままPhotoshop2017を立ち上げても、ウインドウ>エクステンションの中にHello Worldという名前の拡張機能が読み込まれていません。

まずは、Bracketsに表示されているmanifest.xmlを編集します。

C:Users\ユーザー名\AppData\Roaming\Adobe\CEP\extensions\com.example.helloworld'CSXSmanifest.xml

<Host Name="PHXS" Version="[15.0,15.9]" />
<Host Name="PHSP" Version="[15.0,15.9]" />

<Host Name="PHSP" Version="[18.0,18.9]" />
<Host Name="PHXS" Version="[18.0,18.9]" />

に書き換えます。

※ バージョン参考

・CC2017 Version 18

・CC2015 Version 16

・CC2014 Version 15

※バージョンを[18.0,18.9]と2つ書いているのはその2つのバージョン内という意味

[/tl]
[tl label=’STEP.5′ title=’>署名の設定の必要’]

Photoshop2017を立ち上げてウインドウ>エクステンションの中にHello Worldという名前の拡張機能が読み込まれているのを確認します。

ただし、このまま実行しても拡張子を読み込めませんでした。正しくサインされていません。という警告がでます。

[/tl]
[tl label=’STEP.5′ title=’>無署名を許可する’]
レジストリを調整して無署名を許可します。

  • Win+Rからregeditを入力して、レジストリ エディターを起動
  • HKEY_CURRENT_USER/Software/Adobe/CSXS.7まで移動して、右クリックから新規>文字列値から、名前をPlayerDebugMode、値を1

http://chuwa.iobb.net/tech/archive/2013/06/ccplayerdebugmode.html

もう一度、Photoshop2017を立ち上げてウインドウ>エクステンションの中にHello Worldを選択すると、カスタムパネルが起動し、またボタンも機能します。

[/tl]
[/timeline]

.reg作成

.reg作成してみました。

メモ帳に下記のコードをコピペして、PlayerDebugMode_on.regみたな感じで適当な命名+拡張子(reg)に変更。

実行するとレジストリに追記されます。

Windows Registry Editor Version 5.00
[HKEY_CURRENT_USERSoftwareAdobeCSXS.7]
"PlayerDebugMode"="1"

つづいて署名を作成します。

[timeline]
[tl label=’STEP.1′ title=’レジストリ調整’]
自分だけで、完結する場合はレジストリ調整して無署名でよいのですが。
レジストリがいじれない場合や他人に渡す場合などは、署名を作成すれば、警告がでてこなくなります。

[/tl]
[tl label=’STEP.2′ title=’CC Extensions Signing Toolkitのダウンロード’]
下記のURLからCC Extensions Signing Toolkitをダウンロードします。(こちらが最新のようです)

GitHub
GitHub - Adobe-CEP/CEP-Resources: Tools and documentation for building Creative Cloud app extensions... Tools and documentation for building Creative Cloud app extensions with CEP - Adobe-CEP/CEP-Resources

[/tl]
[tl label=’STEP.3′ title=’ZXPSignCmd’]
中身のZXPSignCmd.exeを好きな場所に保存します。

[/tl]
[tl label=’STEP.4′ title=’コマンドプロンプトの起動’]
Win+Rからcmdを入力して、コマンドプロンプトを起動します。

ここで、単純にZXPSignCmd.exeを入力すると、全てのコマンドが表示されます。

[open title=’ZXPSignCmd.exe’]

ZXPSignCmd -sign <inputDirectory> <outputZxp> <p12> <p12Password> [options]
options:
-tsa <timestampURL> - will attempt to timestamp the ZXP using supplied timestamp server. For example, https://timestamp.geotrust.com/tsa
ZXPSignCmd -verify <zxp>|<extensionRootDirectory> [options]
options:
-certInfo - will print out information about certificates (including timestamp and certificate revocation information)
-skipOnlineRevocationChecks - will skip online checks for certificate revocation (certificate revocation checks only happen with -certInfo flag set)
-addCerts <certificate1> <certificate2>... - will verify certificate chain and assess whether or not DER encoded certificates passed in are included
ZXPSignCmd -selfSignedCert <countryCode> <stateOrProvince> <organization> <commonName> <password> <outputPath.p12> [options]
options:
-locality <locality> -orgUnit <orgUnit> -email <email> -validityDays <validityDays> - are optional attributes for self-signed p12 certificates
```ZXPSignCmd -sign <inputDirectory> <outputZxp> <p12> <p12Password>```

[/open]

[/tl]
[tl label=’STEP.5′ title=’署名を作成’]

ZXPSignCmd -selfSignedCert
<outputPath.p12>

[ZXPSignCmd.exeのパス] -selfSignedCert [国] [地域] [組織] [名前] [パスワード] [保存するファイル名]


C:Users\ユーザー名\ZXPSignCmd.exe -selfSignedCert JP Tokyo My MIN test custompanel.test

[/tl]
[tl label=’STEP.6′ title=’パッケージ化’]

ZXPSignCmd -sign

[ZXPSignCmd.exeのパス] -sign [Extensionのソースフォルダのパス] [保存するzxpのパス] [署名のパス] [署名のパスワード]

C:Users\ユーザー名\ZXPSignCmd.exe -sign "C:Users\ユーザー名\AppData\Roaming\Adobe\CEP\extensions\com.example.helloworld'" custompanel.zxp custompanel.test test

custompanel.zxpが作成されます。

[/tl]
[tl label=’STEP.2′ title=’解凍’]
ちなみに.zxpはただのZIPファイルなので、試しに解凍してみます。

META-INFフォルダと言うものが追加されていて、その中にsignatures.xmlというファイルが署名になります。

shock the blog
作ったらやっちゃおう!自作Adobe ExtensionのzxpへのパッケージとExManCmdによるインストール 1/2 Extensi... 連載記事AdobeCCのExtensionをBracketsで開発しようを読破して、目出度くExtension

[/tl]
[/timeline]

最後にカスタムパネルから設定した機能を実行してみましょう!

[timeline]
[tl label=’STEP.1′ title=’JSXの編集’]

Hello Worldのサンプルデータ
C:Users\ユーザー名\AppData\Roaming\Adobe\CEP\extensions\com.example.helloworld'
から、カスタマイズしてみます。

jsx > hostscript.jsxの中身を以前、CGメソッドで作成したスクリプトを置換します。

function makeGroup(){
//顔
var layer_face = app.activeDocument.layerSets.add();
var layer_face_paint = layer_face.layerSets.add();
var layer_face_line = layer_face.layerSets.add();
layer_face.name = '顔';
layer_face_paint.name = '塗り';
layer_face_line.name = '線画';
//見本
var layer_template = app.activeDocument.layerSets.add();
layer_template.name = '見本';
}

[/tl]
[tl label=’STEP.2’JSの編集’]
js > main.js から先程の関数(makeGroup)を記述します。

(function () {
'use strict';
var csInterface = new CSInterface();
function init() {
themeManager.init();
$("#btn_test").click(function () {
csInterface.evalScript('makeGroup()');
});
}
init();
}());

関数がわからない時

evalFile関数を使用して、もう1スクリプト間にかまします。

function AAA() {
var external = $.evalFile("C:/Users/AAA.jsx");
}

[/tl]
[tl label=’STEP.3’HTMLの編集’]

index.htmlを編集します。今回はボタン名だけ変えてみます。

<button id="btn_test" class="topcoat-button--large hostFontSize">グループ作成</button>

あとはお好みでCSSなり画像なり入れて、パネルをカスタマイズしていきます。

[/tl]
[tl label=’STEP.4’カスタムパネルの実行’]
最後にテスト!

[/tl]
[/timeline]

###[ 簡易版]拡張機能でカスタムパネルを表示する方法

要素を最小限にして、カスタムパネルを表示させてみます。

[timeline]
[tl label=’STEP.1′ title=’下記のパスにTESTというフォルダを作成’]
%USERPROFILE%\AppData\Roaming\Adobe\CEP\extensions

[/tl]
[tl label=’STEP.2′ title=’フォルダを作成’]
階層下にCSXSというフォルダを作成

さらにCSXSの中に
manifest.xml
というファイルを作成

[/tl]
[tl label=’STEP.3′ title=’コードの書き換え’]
manifest.xmlの中身を下記のコードをコピペ

[open title=’manifest.xml’]

<?xml version="1.0" encoding="UTF-8"?>
<ExtensionManifest Version="5.0" ExtensionBundleId="com.example.test" ExtensionBundleVersion="1.0"
ExtensionBundleName="TEST" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ExtensionList>
<Extension Id="com.example.test" Version="1.0" />
</ExtensionList>
<ExecutionEnvironment>
<HostList>
<!-- Uncomment Host tags according to the apps you want your panel to support -->
<!-- Photoshop -->
<Host Name="PHSP" Version="[18.0,18.9]" />
<Host Name="PHXS" Version="[18.0,18.9]" />
</HostList>
<LocaleList>
<Locale Code="All" />
</LocaleList>
<RequiredRuntimeList>
<RequiredRuntime Name="CSXS" Version="5.0" />
</RequiredRuntimeList>
</ExecutionEnvironment>
<DispatchInfoList>
<Extension Id="com.example.test">
<DispatchInfo >
<Resources>
<MainPath>./index.html</MainPath>
<ScriptPath>./jsx/hostscript.jsx</ScriptPath>
</Resources>
<Lifecycle>
<AutoVisible>true</AutoVisible>
</Lifecycle>
<UI>
<Type>Panel</Type>
<Menu>TEST</Menu>
<Geometry>
<Size>
<Height>300</Height>
<Width>300</Width>
</Size>
<!--<MinSize>
<Height>550</Height>
<Width>400</Width>
</MinSize>
<MaxSize>
<Height>550</Height>
<Width>400</Width>
</MaxSize>-->
</Geometry>
<Icons>
<Icon Type="Normal">./icons/suimin.png</Icon>
</Icons>
</UI>
</DispatchInfo>
</Extension>
</DispatchInfoList>
</ExtensionManifest>

[/open]

以上で、manifest.xmlだけでも、Photoshopを起動すると拡張機能にTESTのパネルが追加されています。

[/tl]
[tl label=’STEP.4′ title=’アイコン画像を追加’]
さらにiconsフォルダを作成して、その中に画像(suimin.png)を追加

[/tl]
[tl label=’STEP.5′ title=’index.htmlを作成’]
index.htmlを作成、中身は下記のコードに

<html>
<head>
</head>
<img src="icons/suimin.png">
</html>

パネルの中に画像が表示できました。

ちゃんとデータの役割を理解すると、カスタムパネルの作成も簡単に感じます。

[/tl]
[/timeline]

拡張機能のカスタムパネルのHTML・CSSの調整方法

ここからは応用編です。CSS等を追加して見た目や機能を追加していきます。

適当にスクリプトを追加して、タブをつけて、中はアコーディオン式に展開できるように変更してみました。

JSX(hostscript.jsx)

hostscript.jsxから使う機能のスクリプトを読み込んでいるのですが、さらに外部参照にしました。

[timeline]
[tl label=’STEP.1′ title=’フォルダ作成’]
同階層にscriptsフォルダを作成して、使う機能(AAA.jsx)のスクリプトを置く

[/tl]
[tl label=’STEP.2′ title=’パスの追記’]
hostscript.jsxには#include "/c/Users/ユーザー名/AppData/Roaming/Adobe/CEP/extensions/custompanel/jsx/scripts/AAA.jsx"とだけ記述

※ 相対パスだと上手く行かなかったので、絶対パスにしています。

[/tl]
[/timeline]

JavaScript(main.js)

ボタンを押した時に機能が動くような記述を追加するだけ

  $("#AAA").click(function () {
csInterface.evalScript('AAA()');
});

HTML(index.html)

[timeline]
[tl label=’STEP.1′ title=’アコーディオンを追加’]

最初から展開する場合は

[/tl]
[tl label=’STEP.2′ title=’タブを追加’]

ヘッド<head></head>間に下記のコードを追加

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
$(function() {
$(".tab li").click(function() {
var num = $(".tab li").index(this);
$(".tabContent").removeClass('active');
$(".tabContent").eq(num).addClass('active');
$(".tab li").removeClass('active');
$(this).addClass('active')
});
});
</script>

ボディ<body></body>の中の先頭に下記のコードを追加

[/tl]
[tl label=’STEP.3′ title=’タブの中身’]

先頭は
div class="tabContent active"></div>

残りは
<div class="tabContent"></div>
で区切る

※CSSも設定しないと上手くタブが作動しません。

[/tl]
[/timeline]

CSS(styles.css)

参照しているスタイルシートはこちら
topcoat-desktop-dark.min.cssを使用。

[timeline]
[tl label=’STEP.1′ title=’ボタンのラベルを中央合わせに’]

div { text-align : center ; }

[/tl]
[tl label=’STEP.2′ title=’ボタンのサイズをまとめて記述’]

.topcoat-button--large--cta{
width: 100%;
}
.topcoat-button--large{
width: 100%;
}

[/tl]
[tl label=’STEP.2′ title=’タブ関係’]

[open title=’タブ関係’]

ul.tab {
width: 100%;
list-style: none;
padding-left: 0;
}
ul.tab li {
float: left;
height: 30px;
font-family:inherit;
vertical-align: middle;
color:inherit;
font-size:inherit;
text-align: center;
width: 33.3%;
padding: 0 10px;
background-color: #595b5b;
color: #fff;
cursor: default;
}
ul.tab li:hover {
background-color: #539fe1;
color: #fff;
}
ul.tab li.active {
background-color: #368bdc;
color: #fff;
}
div.tabContent {
clear: both;
width: 100%;
display: none;
}
div.active {
display: block;
}

[/open]

[/tl]
[/timeline]

あわせて読みたい

XML(manifest.xml)

パネル名、拡張機能名がhelloworldのままだったので、Custom Panelに変更しました。

※ Photoshopを再起動しないと変更されません。

あわせて読みたい
シンプルで使いやすいタブメニューを超簡単に作成する方法 - ゲマステ!- 新作ゲームレビュー, マイクラ, ... タブごとに中身の替わるタブメニューを、ホームページに超簡単に作成する方法についてご紹介します!

拡張機能のカスタムパネルのデータを外部参照する方法

こちらも応用編です。

拡張機能のカスタムパネルの内容を更新するときに

  • hostscript.jsx
  • main.js
  • index.html

を変更して、それぞれの環境でデータを差し替えしていたのですが、手間なので外部参照してみました。

jsxの外部参照方法

#include "/C/Users/Namae/AppData/Roaming/Adobe/CEP/extensions/custompanel/jsx/hostscript.jsx"

というふうに参照先のパスを書くだけです。

参照先がさらにインクルードされていても、参照されます。

jsの外部参照方法

index.htmlに<script src="js/main.js"></script>と書かれている部分を

<script src="C:/Users/Namae/AppData/Roaming/Adobe/CEP/extensions/custompanel/js/main.js"></script>

というふうに参照先のパスを書くだけです。

htmlの外部参照方法

ここは手間取りました。

まずはinclude.js作成。

[open title=’include.js’]

function include(filename, afterfunc) {
    include.seq = (include.seq) ? include.seq + 1 : 1;
    var id = new Date().getTime() + "-" + include.seq;
    var inc = document.createElement("iframe");
    inc.id = "inc-" + id;
    inc.src = filename;
    inc.style.display = "none";
    document.write("<span id="" + id + ""></span>");
    var incfunc = function() {
        var s = (function() {
            var suffix = (n = filename.lastIndexOf(".")) >= 0 ? filename.substring(n) : "default";
            if (suffix == ".html") return inc.contentWindow.document.body.innerHTML;
            if (suffix == ".txt") return inc.contentWindow.document.body.firstChild.innerHTML;
            if (suffix == "default") return inc.contentWindow.document.body.innerHTML;
        })();
        var span = document.getElementById(id);
        var insertBeforeHTML = function(htmlStr, refNode) {
            if (document.createRange) {
                var range = document.createRange();
                range.setStartBefore(refNode);
                refNode.parentNode.insertBefore(range.createContextualFragment(htmlStr), refNode);
            } else {
                refNode.insertAdjacentHTML('BeforeBegin', htmlStr);
            }
        };
        insertBeforeHTML(s.split(">").join(">").split("<").join("<"), span);
        document.body.removeChild(inc);
        span.parentNode.removeChild(span);
        if (afterfunc) afterfunc();
    };
    if (window.attachEvent) {
        window.attachEvent('onload',
            function() {
                document.body.appendChild(inc);
                inc.onreadystatechange = function() {
                    if (this.readyState == "complete") incfunc();
                };
            });
    } else {
        document.body.appendChild(inc);
        inc.onload = incfunc;
    }
}

[/open]

あとはindex.htmlの中にインクルードするだけです。

[open title=’index.html’]

< !doctype html >
    < html >
    < head >
    < meta charset = "utf-8" >
    < link rel = "stylesheet"
href = "css/topcoat-desktop-dark.min.css" / >
    < link id = "hostStyle"
rel = "stylesheet"
href = "css/styles.css" / >
    < script type = "text/javascript"
src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js" > < /script> < script >
    $(function() {
        $(".tab li").click(function() {
            var num = $(".tab li").index(this);
            $(".tabContent").removeClass('active');
            $(".tabContent").eq(num).addClass('active');
            $(".tab li").removeClass('active');
            $(this).addClass('active')
        });
    }); < /script> < title > < /title> < /head> < body class = "hostElt" >
    < ul class = "tab" >
    < li class = "topcoat-button--large hostFontSize active" > メニューA < /li> < li class = "topcoat-button--large hostFontSize" > メニューB < /li> < li class = "topcoat-button--large hostFontSize" > メニューC < /li> < /ul> < script type = "text/javascript"
src = "js/include.js" > < /script> < script type = "text/javascript" >
    include("C:/Users/Namae/AppData/Roaming/Adobe/CEP/extensions/custompanel/contents.html"); < /script>

[/open]

※中身の参照先contents.htmlの内容はindex.hemlの後半部分

on the center line.
静的HTMLで、インクルードを実現するためのJavaScript - on the center line. ローカルディスク上に存在する静的HTMLで、外部ファイルをインクルードするためのスクリプト(つまり、XMLHttpRequestオブジェクトの代わり)。以前にも同じようなエントリ...

全記事一覧

  • URLをコピーしました!

Photoshopに関する参考記事・ツール・書籍のまとめ

Photoshopのソフトウェア購入

Photoshopが学べるスクール

Photoshopの参考書籍

独学で勉強できてしまうPhotoshopですが、他の人の手法を見ると全然使いこなせてなかったことに気がつくこともあります

著:まきの ゆみ
¥2,178 (2024/04/20 07:06時点 | Amazon調べ)
著:大谷 キミト
¥2,750 (2024/04/22 08:13時点 | Amazon調べ)
目次