リンクをクリップボードにコピー
コピー完了
Adobe Photoshop バージョン : 22.5.1
(バージョン2020でも同じ現象です)
下記スクリプトを実行した際、エラーが出るレイヤーとエラーが出ないレイヤーがあります。
-----------------------------------------------
alert(activeDocument.activeLayer.textItem.size);
-----------------------------------------------
添付のPSDファイルの
レイヤー「123a」を選択しスクリプトを実行すると、エラーが出ます。
レイヤー「123b」を選択しスクリプトを実行しても、エラーが出ません。
「123a」は新規ドキュメントを作成し、テキストを新規で作成したものです。
「123b」は「123a」をコピーし、サイズを手動で入力しなおしたものです。
他の方が作成したフォント関係のスクリプトでも同様のエラーが出て困っています。
フォントサイズを入力しなおせばエラーは出ないのですが、
レイヤーが多量にあるため現実的ではございません。
エラーを回避しつつフォントサイズを取得したいのですが、ご教授いただけませんでしょうか。
よろしくお願いいたします。
リンクをクリップボードにコピー
コピー完了
解決策じゃなくて恐縮なのですが(おそらく当該バージョン固有のバグかと…)
実際 40.48pt のはずが実行結果で 11.9998197555542 pt ですね。
参照したプロパティと文字パネル上の値の齟齬が理解できずにいます。
CC2019(20.0.9)と2020(21.2.12)で添付いただいたpsdを開いた場合も同様でした。
上記の下位バージョンで新規ドキュメントに同様のテキストレイヤーを作成したところ、正常な返り値が出ました。
今のところ、現状の2021でこの処理はおすすめできない、といった見解です。
リンクをクリップボードにコピー
コピー完了
ご検証いただき有難うございます。
値の相違については当方でも悩みましたが、以下のサイトで解決いたしました。
https://qiita.com/takezoux2/items/f739f4b2a885458214a7
(こちらの方が作成されたスクリプトを使用しても、「123a」でエラーが出てしまいますが・・・)
現バージョンでフォントを作成した時点でテキストレイヤーが持っているバグ(?)
という事になるのでしょうか(必ず発生する訳ではないのがまた謎です)。
大量にテキストレイヤーを作成してしまった後なので頭を抱えておりますが、
今の所は地道に値を入れなおしていくしかなさそうですね・・・
リンクをクリップボードにコピー
コピー完了
ありがとうございます。不勉強でした。
2017年の記事ということは、2020以前のバージョンでも万全ではなかったんですね。。
さきほどの検証はただ簡素にテキストレイヤーを作成しただけだったので気付きませんでした。
自由変形で200%拡大したらこれでした
----------
123aからでもテキストレイヤーの名前、コンテンツ、カラー、フォントまでは拾えるようなので、
・文字サイズにばらつきがない
・単一行(行送りも拾えたんですが例によって信用ならない値だったので)
・その他イタリックなどもなし
といったプレーンな状態であれば、レイヤーをループして同内容の新規レイヤーと入れ替えてサイズはbounds頼み、それが終わってからサイズ取得の処理を、というのは可能かもしれませんね。
リンクをクリップボードにコピー
コピー完了
エラーが出るレイヤーを何とかできないか、ばかり考えていたので
外堀から攻めていく方法は目からうろこでした。
プレーンな状態ではあるので、確かにご提案頂いた方法で何とかなりそうな気がします。
スクリプトは不慣れなため時間がかかりそうですが、頑張ってみたいと思います。
有難うございました。
リンクをクリップボードにコピー
コピー完了
スクリプト書いてる間に終わったかな? 一応書いておきます。
そもそもPhotoshopのスクリプトには次の問題があります。
・ドキュメントの作成(つまり設定していく)が主目的で、情報を取得することは考えてない
・CC2015.5が最新で、それ以降更新されてない
ExtensScript Toolkitで提示されたデータでtextItemの情報を取得してみました。(Photoshopは22.5.1)
123aのレイヤー
123bのレイヤー
123aの方はそもそもsizeプロパティが存在していないですね。また、どちらもcontentsプロパティが取得できていないので、どんな内容のテキストなのかわからないというのは致命的です。他にもエラーになっているものがあるので、まあ、まともに使えるものではないです。
このように取得はできませんが設定はできるんです。つまり
alert(activeDocument.activeLayer.textItem.size);
はエラーですが
activeDocument.activeLayer.textItem.size = "40pt";
はエラーになりません。
これを利用すると、「最初のレイヤーの高さを取得しておいて(これはエラーにならない)、あとはフォントサイズを変えてみて高さが一番近くなるものを近似値とする」という方法が取れます。
試しに書いたコードがこちら。
var tlayer = app.activeDocument.activeLayer;
var orgH = tlayer.bounds[3] - tlayer.bounds[1];
var newH;
var sizenum = 12;
var addnum = 0.5;
tlayer.textItem.size = sizenum + "pt";
while (newH < orgH) {
sizenum = sizenum + addnum;
tlayer.textItem.size = sizenum + "pt";
newH = tlayer.bounds[3] - tlayer.bounds[1];
}
alert(sizenum + "pt");
orgHが元のレイヤーの高さ、newHがフォントサイズを設定したときの高さです。フォントサイズは12ptから始めて0.5pt刻みで上げて行ってます。どこまでの精度が必要かわかりませんのでこの数字を適当に変更してもらえばよいと思います。ただあまり細かく刻むとかなり時間がかかります。ご参考まで。
リンクをクリップボードにコピー
コピー完了
ご返信を有難うございます。
(他の作業をしていたため、まだ手付かず状態です)
最近スクリプトを触り始め、データ出力が快適に出来るかも・・・と思っていたのですが、
なかなか思うようには行かないものですね・・・。
まだまだ知らない事ばかりで ExtensdScript Toolkit なるものも初めて知りました。
頂いたスクリプトを参考に、自分でも試行錯誤してみたいと思います。
(ちなみに1pt刻みです)
色々とご教授いただき有難うございました!
リンクをクリップボードにコピー
コピー完了
どんなテキストレイヤーにも対応できるかは分かりませんが、
何とか出来たような気がしますので共有いたします。
//------------------------------------------------------------------------
/*
問題点①:
テキストレイヤーにスケールをかけると正しいfontsizeが取得できない。
この場合、textItem.sizeにスケール値をかけてやる必要がある。
問題点②:
テキストレイヤーのフォントサイズを取得時エラーが出るものがある。
コンテンツを再入力した後だと何故かエラーが出ない。
ただし、テキストレイヤーをスケールした場合コンテンツ再入力でフォントサイズが変わる。
この時点の正しいサイズを得るため、textItem.sizeにスケール値をかけてやる必要がある。
*/
var tlayer = app.activeDocument.activeLayer;
//今の高さ
var orgHt = tlayer.bounds[3]-tlayer.bounds[1];
//コンテンツを再入力
var contents = tlayer.textItem.contents;
tlayer.textItem.contents = contents;
//再入力後の高さ
var newHt = tlayer.bounds[3]-tlayer.bounds[1];
//フォントサイズを取得(ここだとエラーは出ない)
var orgSize = tlayer.textItem.size;
//コンテンツ再入力したのでそれをアンドゥ
undo();
//スケールされてる場合、スケール値を返す関数(らしい)
var scaleFct = getFontScaleSize(tlayer);
//スケール値をかける
var nowSize = orgSize*scaleFct;
//コンテンツ再入力前後の大きさに差異がある場合更にスケール値をかけてやる
if (orgHt!=newHt){
nowSize = nowSize*scaleFct;
}
//丸める
nowSize = Math.round(nowSize*100)/100;
////////////////////////
alert(nowSize);
////////////////////////
//------------------------------------------------------------------------
function undo() {
executeAction(charIDToTypeID('undo'), undefined, DialogModes.NO);
}
//------------------------------------------------------------------------
//参照:https://qiita.com/takezoux2/items/f739f4b2a885458214a7
//レイヤーがスケールされている場合のスケール値を返す(内容は理解していない)
function getFontScaleSize(layer /* ArtLayer */ ){
var mFactor = 1;
activeDocument.activeLayer = layer;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref).getObjectValue(stringIDToTypeID('textKey'));
if (desc.hasKey(stringIDToTypeID('transform'))) {
mFactor = desc.getObjectValue(stringIDToTypeID('transform')).getUnitDoubleValue (stringIDToTypeID("yy") );
}
return mFactor;
}
リンクをクリップボードにコピー
コピー完了
スクリプトに不慣れとは思えないほど見やすい書き方をされていて驚きです!
@Omachi さんのコードをもとに、元サイズpx / 暫定サイズpx * 暫定pt などで一発出しできないものかと少しいじってみてたんですが分母が小さいと誤差が出るため41.35pt(誤差1px)が限界でした。。
ともあれ解決されてよかったです。
次期バージョン以降も直らないんでしょうかねこの仕様。