Скрипт забирает самый новый файл из указанной папки и вписывает его в границы активного выделения в Фотошопе.
SD_Output = ['d:/Downloads'] - в кавычках путь к папке, можно указать несколько папок (через запятую, каждый путь в кавычках). Обратите внимание на косую черту - нужно заменить \ на / как в примере.
EXTENSIONS = ['png', 'jpg', 'jpeg'] - какие файлы искать
REMOVE_FILE = true; - удалять файл после того как он вставлен или нет.
#target photoshop
const SD_Output = ['d:/Downloads'],
EXTENSIONS = ['png', 'jpg', 'jpeg'],
LAYER_NAME = "Generated image",
REMOVE_FILE = true;
var doc = new AM('document'),
lr = new AM('layer'),
apl = new AM('application'),
ch = new AM('channel'),
s2t = stringIDToTypeID,
t2s = typeIDToStringID;
if (apl.getProperty('numberOfDocuments')) activeDocument.suspendHistory('Paste generated image', 'main()')
function main() {
if (doc.hasProperty('selection')) {
var pth = browseFolder(SD_Output);
if (pth.length) {
pth.sort(function (x, y) {
return x.time < y.time ? 1 : -1
});
var bounds = doc.descToObject(doc.getProperty('selection').value);
try {
doc.place(pth[0].file)
var placedBounds = doc.descToObject(lr.getProperty('bounds').value);
var dW = (bounds.right - bounds.left) / (placedBounds.right - placedBounds.left);
var dH = (bounds.bottom - bounds.top) / (placedBounds.bottom - placedBounds.top)
lr.transform(dW * 100, dH * 100);
lr.rasterize();
lr.setName(LAYER_NAME)
if (REMOVE_FILE) pth[0].file.remove();
} catch (e) { }
}
}
}
function findAllFiles(srcFolder, fileObj, useSubfolders) {
if (!srcFolder) return
var fileFolderArray = Folder(srcFolder).getFiles(),
subfolderArray = [];
for (var i = 0; i < fileFolderArray.length; i++) {
var fileFoldObj = fileFolderArray[i];
if (fileFoldObj instanceof File) {
if (!fileFoldObj.hidden && isOneOfThese(fileFoldObj.name)) fileObj.push(
{
file: fileFoldObj,
time: fileFoldObj.created.getTime()
}
)
} else if (useSubfolders) {
subfolderArray.push(fileFoldObj)
}
}
if (useSubfolders) {
for (var i = 0; i < subfolderArray.length; i++) findAllFiles(subfolderArray[i], fileObj, useSubfolders)
}
}
function isOneOfThese(s) {
s = decodeURI(s).toLocaleUpperCase();
for (a in EXTENSIONS) {
if (s.lastIndexOf(EXTENSIONS[a].toLocaleUpperCase()) == s.length - EXTENSIONS[a].length) return true
}
return false
}
function browseFolder(fol) {
if (!fol.length) fol = [(new Folder()).selectDlg()]
var pth = [];
for (a in fol) {
var cur = new Folder(fol[a]);
if (cur.exists) findAllFiles(cur, pth, true)
}
return pth
}
function AM(target, order) {
var s2t = stringIDToTypeID,
t2s = typeIDToStringID;
target = target ? s2t(target) : null;
this.getProperty = function (property, descMode, id, idxMode) {
property = s2t(property);
(r = new ActionReference()).putProperty(s2t('property'), property);
id != undefined ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id)) :
r.putEnumerated(target, s2t('ordinal'), order ? s2t(order) : s2t('targetEnum'));
return descMode ? executeActionGet(r) : getDescValue(executeActionGet(r), property);
}
this.hasProperty = function (property, id, idxMode) {
property = s2t(property);
(r = new ActionReference()).putProperty(s2t('property'), property);
id ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id))
: r.putEnumerated(target, s2t('ordinal'), s2t('targetEnum'));
try { return executeActionGet(r).hasKey(property) } catch (e) { return false }
}
this.descToObject = function (d) {
var o = {}
for (var i = 0; i < d.count; i++) {
var k = d.getKey(i)
o[t2s(k)] = getDescValue(d, k)
}
return o
}
this.place = function (pth) {
var descriptor = new ActionDescriptor();
descriptor.putPath(s2t("null"), pth);
descriptor.putBoolean(s2t("linked"), true);
executeAction(s2t("placeEvent"), descriptor, DialogModes.NO);
}
this.makeSelection = function (top, left, bottom, right) {
(r = new ActionReference()).putProperty(s2t('channel'), s2t('selection'));
(d = new ActionDescriptor()).putReference(s2t('null'), r);
(d1 = new ActionDescriptor()).putUnitDouble(s2t('top'), s2t('pixelsUnit'), top);
d1.putUnitDouble(s2t('left'), s2t('pixelsUnit'), left);
d1.putUnitDouble(s2t('bottom'), s2t('pixelsUnit'), bottom);
d1.putUnitDouble(s2t('right'), s2t('pixelsUnit'), right);
d.putObject(s2t('to'), s2t('rectangle'), d1);
executeAction(s2t('set'), d, DialogModes.NO);
}
this.transform = function (dw, dh) {
(d = new ActionDescriptor()).putEnumerated(s2t("freeTransformCenterState"), s2t("quadCenterState"), s2t("QCSAverage"));
(d1 = new ActionDescriptor()).putUnitDouble(s2t("horizontal"), s2t("pixelsUnit"), 0);
d1.putUnitDouble(s2t("vertical"), s2t("pixelsUnit"), 0);
d.putObject(s2t("offset"), s2t("offset"), d1);
d.putUnitDouble(s2t("width"), s2t("percentUnit"), dw);
d.putUnitDouble(s2t("height"), s2t("percentUnit"), dh);
executeAction(s2t("transform"), d, DialogModes.NO);
}
this.setName = function (title) {
(r = new ActionReference()).putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
(d = new ActionDescriptor()).putReference(s2t("null"), r);
(d1 = new ActionDescriptor()).putString(s2t("name"), title);
d.putObject(s2t("to"), s2t("layer"), d1);
executeAction(s2t("set"), d, DialogModes.NO);
}
this.rasterize = function () {
(d = new ActionDescriptor()).putReference(s2t('target'), r);
executeAction(s2t('rasterizePlaced'), d, DialogModes.NO);
}
function getDescValue(d, p) {
switch (d.getType(p)) {
case DescValueType.OBJECTTYPE: return { type: t2s(d.getObjectType(p)), value: d.getObjectValue(p) };
case DescValueType.LISTTYPE: return d.getList(p);
case DescValueType.REFERENCETYPE: return d.getReference(p);
case DescValueType.BOOLEANTYPE: return d.getBoolean(p);
case DescValueType.STRINGTYPE: return d.getString(p);
case DescValueType.INTEGERTYPE: return d.getInteger(p);
case DescValueType.LARGEINTEGERTYPE: return d.getLargeInteger(p);
case DescValueType.DOUBLETYPE: return d.getDouble(p);
case DescValueType.ALIASTYPE: return d.getPath(p);
case DescValueType.CLASSTYPE: return d.getClass(p);
case DescValueType.UNITDOUBLE: return (d.getUnitDoubleValue(p));
case DescValueType.ENUMERATEDTYPE: return { type: t2s(d.getEnumerationType(p)), value: t2s(d.getEnumerationValue(p)) };
default: break;
};
}
}
А это скрипт для того чтобы любое прямоугольное выделение было кратно 8 пикселам:
(копировать код, сохранить как jsx, кинуть в папку скриптов фотошопа, запустить скрипт из под Фотошопа - он предложит включить отслеживание выделений, после нажатия кнопки "включить" будет поправлять все прямоугольные выделения. Отключается повторным запуском и нажатием "отключить")
https://raw.githubusercontent.com/boogalooper/Snippets/refs/heads/master/Tools/Tools%20-%20marqueeRectTool%20x8.jsx