Photoshopで開いている画像をInDesignに配置したサイズにリサイズするAppleScript

ずっと使っているjsx版をAppleScriptに書き換えました。
ESTKデバッグ環境が無くなり、AppleSilicon上でのVSCodeでの環境構築がちょっとめんどい…のでAppleScriptの方が見渡しがよいと思い。
あとBridgetalkはもう触りたくない。inddであってもだ！

- Photoshop側をメインに実行する。アラートもPs側から出す（ぱしぱし切り替えられると面倒なので）
- 開いている画像と同じファイルパスのものからhorizontal scaleを取得（最も正確な値が取れるので）
- 拡大率で処理を分岐。設定拡大率以上になる場合と、あまりリサイズされない場合はその旨表示してキャンセルボタンをデフォルトにする
- 実行したことを、Photoshopドキュメントのヒストリーに記録する（ヒストリーなのでファイルを閉じると消える）
- この後USM等でのシャープ処理を行うため、ピクセル等倍にする

Linksフォルダ内の画像をBridgeで一覧表示し、順番に1枚ずつPhotoshopで処理するために作成しました。
リサイズに伴うモアレ発生の確認や、画像毎に異なるシャープ処理を行うためです。
上記の理由から全リンク一括処理は、画像に最適化された処理が行えないこともあり大変危険だと考えています。


```AppleScript:
(*===================================
ターゲット解像度と、リサイズ限界値の変数設定
===================================*)

set newPPI to 350 -- 解像度設定
--Keyboard Maestroから実行する場合、解像度をVariableに入れておく。
--Keyboard Maestroを使わない場合は下の1行をコメントアウト
tell application "Keyboard Maestro Engine" to set newPPI to getvariable "targetPPI"

set scaleMax to 200 -- この倍率を超えたら処理の停止勧告

--この倍率以内なら処理の停止勧告（無駄な処理で劣化させないため）
set efScaleMax to 110
set efScaleMin to 90

(*===================================
Photoshopの処理
画像ファイルのパス名とピクセル幅を取得
===================================*)

tell application id "com.adobe.photoshop"
	
	-- ドキュメントが開かれていなければ中止する
	if (count of documents) is 0 then
		display alert "⚠️開いているドキュメントがありません。"
		return
	end if
	
	--スナップショットに"ResizeImagebyAS"があるなら中止する
	if (do javascript "(function(){var myH=app.activeDocument.historyStates;for(i=0;i<myH.length;i++){if(myH[i].snapshot && myH[i].name=='ResizeImagebyAS'){return 1}}return 0;}())") = "1" then
		display alert "⚠️実行済みです" & return & "再度実行する際は、" & return & "ヒストリーパネルのスナップショット" & return & "\"ResizeImagebyAS\"" & return & "を削除してください"
		return
	end if
	
	set psDoc to current document
	set ruler units of settings to pixel units
	set psPath to POSIX path of (get file path of psDoc)
	set psPXWidth to width of psDoc
	set psPPI to resolution of psDoc
	
end tell

(*===================================
InDesignで全リンクを探し、パス名が同じかつリンク更新状態が正常
配置サイズが最大のものの水平拡大率を取得
===================================*)

tell application id "com.adobe.indesign"
	-- ドキュメントが開かれていなければ中止する
	if (count of documents) is 0 then
		my PSMsg("⚠️inDesignドキュメントが開かれていません。")
		return
	end if
	
	set idDoc to active document
	set idLinks to links of idDoc
	set mlMax to 0
	
	repeat with i in idLinks
		if file path of i = psPath then
			if status of i is normal then
				set ML to absolute horizontal scale of parent of i
				if mlMax < ML then
					set mlMax to ML
				end if
			else
				-- リンクステータスが正常でない場合終了
				my PSMsg("⚠️リンクが更新されていないため、正しいサイズを取得できません。")
				return
			end if
		end if
	end repeat
	-- リンクが見つからない場合終了
	if mlMax is 0 then
		my PSMsg("⚠️ドキュメント中にリンクが存在しません。")
		return
	end if
end tell

(*===================================
Photoshopリサイズ処理
===================================*)

tell application id "com.adobe.photoshop"
	
	--現在の横幅mmと、newPPIを適用した新しい横幅pxサイズを計算
	set currentWidthMM to psPXWidth / psPPI * 25.4 * (mlMax / 100)
	set newWidthPX to (currentWidthMM * (newPPI / 25.4) + 0.5) div 1
	
	--拡大・縮小で処理を分ける。scaleMaxを越えていたら中止勧告
	set scaleRatio to (newWidthPX / psPXWidth * 100 + 0.5) div 1
	set scaleAlert to ""
	
	if scaleRatio > scaleMax then
		set defaultBtn to "キャンセル"
		set scaleAlert to "⚠️拡大率が" & (scaleMax as text) & "%を越えています。" & return & "⚠️別の手法で拡大することをお勧めします。"
	else
		if efScaleMin < scaleRatio and scaleRatio < efScaleMax then
			set defaultBtn to "キャンセル"
			set scaleAlert to (("⚠️拡大率が" & efScaleMin as text) & "％～" & efScaleMax as text) & "％程度です。" & return & "⚠️不要な劣化を避けるため、処理しないことをお勧めします。"
		else
			set defaultBtn to "実行"
		end if
	end if
	
	set dialogMessage to ((((psPXWidth + 0.5) div 1 as text) & " px（配置サイズ：" & ((currentWidthMM + 0.05) div 0.1 / 10) & "mm）" & return & "▼" & ((scaleRatio + 0.5) div 1) as text) & "%" & return & ((currentWidthMM * (newPPI / 25.4) + 0.5) div 1) as text) & " px（" & newPPI & "ppiで" & ((currentWidthMM + 0.05) div 0.1 / 10) & "mm）" & return & scaleAlert
	
	
	display dialog dialogMessage buttons {"キャンセル", "実行"} default button defaultBtn
	if button returned of result is "キャンセル" then
		return
	end if
	
	-- 拡大には「ディテールを保持2.0：ノイズ除去12」、縮小には古い「バイキュービック」を使用
	if scaleRatio < 100 then
		-- 縮小処理
		do javascript "
			var doc = app.activeDocument;
			doc.resizeImage(UnitValue(" & newWidthPX & ", 'px'), null, " & newPPI & ", ResampleMethod.BICUBIC);
			"
		
	else
		-- 拡大処理
		do javascript "
			var doc = app.activeDocument;
			var desc = new ActionDescriptor();
			desc.putUnitDouble(app.charIDToTypeID('Wdth'), app.charIDToTypeID('#Pxl'), " & newWidthPX & ");
			desc.putBoolean(app.stringIDToTypeID('scaleStyles'), true);
			desc.putBoolean(app.stringIDToTypeID('constrainProportions'), true);
			desc.putEnumerated(app.charIDToTypeID('Intr'), app.stringIDToTypeID('interpolationType'), app.stringIDToTypeID('deepUpscale'));
			desc.putInteger(app.stringIDToTypeID('noise'), 12);
			desc.putUnitDouble(app.charIDToTypeID('Rslt'), app.charIDToTypeID('#Rsl'), " & newPPI & ");
			executeAction(app.charIDToTypeID('ImgS'), desc, DialogModes.NO);
			"
	end if
	
	-- USM処理のためピクセル等倍表示
	tell application "System Events" to keystroke "0" using {command down, option down}
	
	--スナップショットに"ResizeImagebyAS"を作り、実行したことを記録する。
	do javascript "
		var idMk=charIDToTypeID('Mk  ');
		var desc7=new ActionDescriptor();
		var idnull=charIDToTypeID('null');
		var ref1=new ActionReference();
		var idSnpS=charIDToTypeID('SnpS');
		ref1.putClass(idSnpS);
		desc7.putReference(idnull,ref1);
		var idFrom=charIDToTypeID('From');
		var ref2=new ActionReference();
		var idHstS=charIDToTypeID('HstS');
		var idCrnH=charIDToTypeID('CrnH');
		ref2.putProperty(idHstS,idCrnH);
		desc7.putReference(idFrom,ref2);
		var idNm=charIDToTypeID('Nm  ');
		desc7.putString(idNm,'''ResizeImagebyAS''');
		var idUsng=charIDToTypeID('Usng');
		var idHstS=charIDToTypeID('HstS');
		var idFllD=charIDToTypeID('FllD');
		desc7.putEnumerated(idUsng,idHstS,idFllD);
		executeAction(idMk,desc7,DialogModes.NO);
		"
end tell

(*===================================
関数
===================================*)

on PSMsg(DispMesg) -- InDesign側でなく、実行側のPsでアラートを出すための関数
	tell application id "com.adobe.photoshop" to display alert DispMesg
end PSMsg
```