
Stephen Marsh
Community Expert
Stephen Marsh
Community Expert
Activity
Community Expert
in Photoshop ecosystem Discussions
‎Mar 05, 2025
08:13 PM
1 Upvote
‎Mar 05, 2025
08:13 PM
1 Upvote
I believe that you are trying to mix oil and water.
Untested, but perhaps the UXP can run an Action, with the action calling the ExtendScript code.
... View more
‎Mar 05, 2025
03:11 PM
To all experiencing this issue, are you saving direct to your computer's local drive, or are you saving over the network or to cabled external media?
... View more
Community Expert
in Photoshop ecosystem Discussions
‎Mar 05, 2025
01:58 PM
1 Upvote
‎Mar 05, 2025
01:58 PM
1 Upvote
Depending on image content and pixel dimensions, the resampling/interpolation algorithm can make a visual difference, so that is why it's there.
A checkbox to disable would be appreciated by some users.
You can use a script that I created to resize without a preview:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/image-preview-in-resize-dialog/m-p/15192988#M856339
... View more
Community Expert
in Photoshop ecosystem Discussions
‎Mar 05, 2025
05:51 AM
1 Upvote
‎Mar 05, 2025
05:51 AM
1 Upvote
@suzy_95
I created the following script to stack alpha-numeric sorting images from two separate folders to a two-layer file. This should get you 90% of the way there. Before the script saves the file to various file formats, an action run by the script can complete any further automation that you require (the action can run another script if more complex processing is required that can't be achieved via an action).
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-to-open-files-and-layer-them/m-p/12532657#U14933502
... View more
Community Expert
in Photoshop ecosystem Discussions
‎Mar 05, 2025
12:39 AM
1 Upvote
‎Mar 05, 2025
12:39 AM
1 Upvote
Another option is to just have standard layers with the 3 hats in an upper layer group, then have the base image in a lower group and use this script:
https://github.com/mechanicious/photoshopCompositionComposer
... View more
‎Mar 04, 2025
01:06 PM
I tried to create a script with ChatGPT, but it didn't work. This one does. Thank you so much.
By @marief2223714
Thank you, you're welcome.
... View more
Community Expert
in Photoshop ecosystem Discussions
‎Mar 04, 2025
01:38 AM
2 Upvotes
‎Mar 04, 2025
01:38 AM
2 Upvotes
I have been working on a generic GUI version of the Data Sets to JPEG script, allowing users to select from JPEG, PNG, WEBP, TIFF and PSB output file formats. Although I could have added PSD, this is covered by the native Data Set export functionality.
/*
Photoshop Variables Data Sets to Files GUI v1-0.jsx
v1.0 - 4rd March 2025, Initial Release
Updated and extended by Stephen Marsh, tested with v2019, v2020, v2021, v2024 and v2025 on Mac and Windows.
Original script by Mike Hale, 2010
NOTE: The active document must have Data Sets already defined.
https://community.adobe.com/t5/photoshop-ecosystem-discussions/using-datasets/td-p/2665594
https://forums.adobe.com/thread/628182
https://forums.adobe.com/message/2773935#2773935
*/
#target photoshop
// Adjust the following "user friendly" variables as required. A GUI for these file format options isn't planned!
// Filename suffix separator
var separator = '_'; // '_' | ' ' | '-' (underscore, space or hyphen)
// saveJPEG global variables
var jpegEmbedColorProfile = true; // Boolean: true | false
var jpegFormatOptions = FormatOptions.STANDARDBASELINE; // FormatOptions.STANDARDBASELINE | FormatOptions.OPTIMIZEDBASELINE | FormatOptions.PROGRESSIVE
var jpegMatte = MatteType.NONE; // MatteType.NONE | MatteType.WHITE | MatteType.BLACK
var jpegQuality = 10; // Numeric: 0 - 12 (low quality to highest quality)
// savePNG global variables
var pngCompression = 1; // Numeric: 0 - 9 (low compression to highest)
var pngInterlaced = false; // Boolean: true | false
// saveWebP global variables
var webPCompressionType = "compressionLossy"; // String: "compressionLossless" | "compressionLossy"
var webPCompIsLossless = false; // Boolean: true | false
var webPQuality = 75; // Numeric: 0 - 100 (low quality to highest quality)
var webPIncludeXMPData = true; // Boolean: true | false
var webPIncludeEXIFData = false; // Boolean: true | false
var webPIncludePsExtras = false; // Boolean: true | false
var webPLowerCase = true; // Boolean: true | false
var webPEmbedProfiles = true; // Boolean: true | false
// saveTIFF global variables
var tiffEmbedColorProfile = true; // Boolean: true | false
var tiffByteOrder = ByteOrder.IBM; // ByteOrder.MACOS | ByteOrder.IBM
var tiffTransparency = true; // Boolean: true | false
var tiffLayerCompression = LayerCompression.ZIP; // LayerCompression.RLE | LayerCompression.ZIP
var tiffInterleaveChannels = true; // Boolean: true | false
var tiffAlphaChannels = true; // Boolean: true | false
var tiffAnnotations = true; // Boolean: true | false
var tiffSpotColors = true; // Boolean: true | false
var tiffSaveLayers = true; // Boolean: true | false
var tiffSaveImagePyramid = false; // Boolean: true | false
var tiffImageCompression = TIFFEncoding.TIFFLZW; // TIFFEncoding.NONE | TIFFEncoding.JPEG | TIFFEncoding.TIFFLZW | TIFFEncoding.TIFFZIP
///// GUI FUNCTION /////
try {
var createDialog = function () {
// Confirm with the user that the file meets the criteria
if (!confirm("Data Sets must be created before running this script. Continue?", false)) {
return;
}
// Create the dialog window
var dlg = new Window('dialog', 'Data Sets to Files (v1.0)');
dlg.preferredSize = [500, 350];
// Create main panel to hold input controls
dlg.mainPanel = dlg.add('panel', undefined, '');
dlg.mainPanel.alignment = ['fill', 'fill'];
dlg.mainPanel.margins = [15, 15, 15, 15];
dlg.mainPanel.spacing = 10;
dlg.mainPanel.alignChildren = 'left';
// CSV File button and path
var csvGroup = dlg.mainPanel.add('group');
csvGroup.orientation = 'column';
csvGroup.alignChildren = 'fill';
csvGroup.alignment = ['fill', 'top'];
csvGroup.add('statictext', undefined, 'Select the Data Set .csv file to import:');
var csvBtnGroup = csvGroup.add('group');
csvBtnGroup.alignment = ['fill', 'top'];
csvBtnGroup.alignChildren = 'left';
dlg.mainPanel.csvFileBtn = csvBtnGroup.add('button', undefined, 'Browse...', { name: 'browse' });
dlg.mainPanel.csvFileBtn.preferredSize.width = 100;
// Add a panel for the CSV file path
var csvPathPanel = csvGroup.add('panel');
csvPathPanel.alignment = ['fill', 'top'];
csvPathPanel.margins = 10;
dlg.mainPanel.csvFilePath = csvPathPanel.add('statictext', undefined, 'No file selected', { truncate: "middle" });
dlg.mainPanel.csvFilePath.alignment = ['fill', 'top'];
dlg.mainPanel.csvFilePath.minimumSize.width = 350;
// Output Folder button and path
var outputGroup = dlg.mainPanel.add('group');
outputGroup.orientation = 'column';
outputGroup.alignChildren = 'fill';
outputGroup.alignment = ['fill', 'top'];
outputGroup.add('statictext', undefined, 'Select the output folder:');
var outputBtnGroup = outputGroup.add('group');
outputBtnGroup.alignment = ['fill', 'top'];
outputBtnGroup.alignChildren = 'left';
dlg.mainPanel.outputFolderBtn = outputBtnGroup.add('button', undefined, 'Browse...', { name: 'browse' });
dlg.mainPanel.outputFolderBtn.preferredSize.width = 100;
// Add a panel for the output folder path
var outputPathPanel = outputGroup.add('panel');
outputPathPanel.alignment = ['fill', 'top'];
outputPathPanel.margins = 10;
dlg.mainPanel.outputFolderPath = outputPathPanel.add('statictext', undefined, 'No folder selected', { truncate: "middle" });
dlg.mainPanel.outputFolderPath.alignment = ['fill', 'top'];
dlg.mainPanel.outputFolderPath.minimumSize.width = 350;
// File Format Group
var formatGroup = dlg.mainPanel.add('group');
formatGroup.orientation = 'column';
formatGroup.alignChildren = 'left';
formatGroup.alignment = ['left', 'top'];
// Add a static text label
formatGroup.add('statictext', undefined, 'Select the output file format:');
// Add a group for the dropdown and description
var formatDropdownGroup = formatGroup.add('group');
formatDropdownGroup.orientation = 'row';
formatDropdownGroup.alignChildren = 'left';
// Create the conditional dropdown options array based on Photoshop version 2022 check/test
var formatOptions = ["JPEG", "PNG", "TIFF", "PSB"];
if (parseFloat(app.version) >= 23) {
formatOptions.splice(2, 0, "WEBP"); // Insert into the array at index 2 (3rd position)
}
// Add a dropdown list for format selection using the conditional format options
dlg.mainPanel.formatList = formatDropdownGroup.add('dropdownlist', undefined, formatOptions);
// Default selection to the first entry (JPEG)
dlg.mainPanel.formatList.selection = 0;
// Set the preferred width for the dropdown list
dlg.mainPanel.formatList.preferredSize.width = 70;
// Add a static text label that updates with format selection
dlg.mainPanel.formatDescription = formatDropdownGroup.add('statictext', undefined, '(' + jpegFormatOptions.toString().replace(/FormatOptions\./, '') + ' Format Option, Quality ' + jpegQuality + ')');
// Add a static text label for filename suffix options
formatGroup.add('statictext', undefined, 'Select the filename suffix:');
// Add a dropdown list for filename suffix options
dlg.mainPanel.suffixList = formatGroup.add('dropdownlist', undefined, ['First Column in CSV', 'Dataset Index No.']);
// Default selection to 'First column in CSV'
dlg.mainPanel.suffixList.selection = 0;
// Set the preferred width for the suffix dropdown list
dlg.mainPanel.suffixList.preferredSize.width = 160;
// Create button group for Cancel and OK buttons
var buttonGroup = dlg.add('group');
buttonGroup.orientation = 'row';
buttonGroup.alignment = 'right';
buttonGroup.spacing = 5;
dlg.cancelBtn = buttonGroup.add('button', undefined, 'Cancel', { name: 'cancel' });
dlg.okBtn = buttonGroup.add('button', undefined, 'OK', { name: 'ok' });
// Update the static text when the dropdown selection changes
dlg.mainPanel.formatList.onChange = function () {
var selectedFormat = dlg.mainPanel.formatList.selection.text;
var descriptions = {
'JPEG': '(' + jpegFormatOptions.toString().replace(/FormatOptions\./, '') + ' Format Option, Quality ' + jpegQuality + ')',
'PNG': '(Lossless Compression ' + pngCompression + ', Supports Transparency)',
'WEBP': '(Lossy Compression ' + webPQuality + ', Supports Transparency)',
'TIFF': '(' + tiffByteOrder.toString().replace(/ByteOrder\./, '') + ' Byte Order, ' + tiffImageCompression.toString().replace(/TIFFEncoding\./, '') + ' Compression)',
'PSB': '(Large Document Format)'
};
dlg.mainPanel.formatDescription.text = descriptions[selectedFormat];
};
// Return the dialog
return dlg;
};
} catch (error) {
alert(error + ', Line: ' + error.line);
}
///// HELPER FUNCTIONS /////
function fileImportDataSets(file) {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putClass(stringIDToTypeID("dataSetClass"));
desc.putReference(charIDToTypeID("null"), ref);
desc.putPath(charIDToTypeID("Usng"), new File(file));
desc.putEnumerated(charIDToTypeID("Encd"), stringIDToTypeID("dataSetEncoding"), stringIDToTypeID("dataSetEncodingAuto"));
desc.putBoolean(stringIDToTypeID("eraseAll"), true);
desc.putBoolean(stringIDToTypeID("useFirstColumn"), true);
executeAction(stringIDToTypeID("importDataSets"), desc, DialogModes.NO);
};
function applyDataSet(setName) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putName(s2t("dataSetClass"), setName);
descriptor.putReference(s2t("null"), reference);
executeAction(s2t("apply"), descriptor, DialogModes.NO);
};
function getDataSetNames(csvFileRef) {
var _ftn = function (string) {
var csvItems = string.split(",");
var datasetName = csvItems[0].replace(/(^['\"]|['\"]$)/g, ''); // Clean both single and double quote-escaped values
return datasetName;
};
csvFileRef.open();
var datasetArray = [];
var i = 0;
var csvString;
while (!csvFileRef.eof) {
csvString = csvFileRef.readln();
// Skip empty lines
if (csvString.length < 2) continue;
datasetArray[i] = _ftn(csvString);
i++;
}
csvFileRef.close();
return datasetArray;
};
function paddedSetNo(number) {
var str = number.toString();
// 4-digit padding (e.g., 1 = 0001, 23 = 0023)
while (str.length < 4) {
str = "0" + str;
}
return str;
}
function jpegSaveOptions() {
var jpgOptions = new JPEGSaveOptions();
jpgOptions.formatOptions = jpegFormatOptions;
jpgOptions.embedColorProfile = jpegEmbedColorProfile;
jpgOptions.matte = jpegMatte;
jpgOptions.quality = jpegQuality;
return jpgOptions;
};
function pngSaveOptions() {
var pngOptions = new PNGSaveOptions();
pngOptions.compression = pngCompression;
pngOptions.interlaced = pngInterlaced;
return pngOptions;
};
function saveWebP(saveFile) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
descriptor2.putEnumerated(s2t("compression"), s2t("WebPCompression"), s2t(webPCompressionType));
if (webPCompIsLossless == false) {
descriptor2.putInteger(s2t("quality"), webPQuality);
}
// Metadata options
descriptor2.putBoolean(s2t("includeXMPData"), webPIncludeXMPData);
descriptor2.putBoolean(s2t("includeEXIFData"), webPIncludeEXIFData);
descriptor2.putBoolean(s2t("includePsExtras"), webPIncludePsExtras);
// WebP format and save path
descriptor.putObject(s2t("as"), s2t("WebPFormat"), descriptor2);
descriptor.putPath(s2t("in"), saveFile);
// The extension
descriptor.putBoolean(s2t("lowerCase"), webPLowerCase);
// Embed color profile
descriptor.putBoolean(s2t("embedProfiles"), webPEmbedProfiles);
// Execute the save
executeAction(s2t("save"), descriptor, DialogModes.NO);
}
function saveTIFF(saveFile) {
var tiffSaveOptions = new TiffSaveOptions();
tiffSaveOptions.embedColorProfile = tiffEmbedColorProfile;
tiffSaveOptions.byteOrder = tiffByteOrder;
tiffSaveOptions.transparency = tiffTransparency;
tiffSaveOptions.layers = tiffSaveLayers;
tiffSaveOptions.layerCompression = tiffLayerCompression;
tiffSaveOptions.interleaveChannels = tiffInterleaveChannels;
tiffSaveOptions.alphaChannels = tiffAlphaChannels;
tiffSaveOptions.annotations = tiffAnnotations;
tiffSaveOptions.spotColors = tiffSpotColors;
tiffSaveOptions.saveImagePyramid = tiffSaveImagePyramid;
tiffSaveOptions.imageCompression = tiffImageCompression;
// Execute the save
app.activeDocument.saveAs(saveFile, tiffSaveOptions, true, Extension.LOWERCASE);
}
function savePSB(saveFile) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
descriptor2.putBoolean(s2t("maximizeCompatibility"), true);
descriptor.putObject(s2t("as"), s2t("largeDocumentFormat"), descriptor2);
descriptor.putPath(s2t("in"), saveFile);
descriptor.putBoolean(s2t("lowerCase"), true);
descriptor.putBoolean(s2t("layers"), true);
// Execute the save
executeAction(s2t("save"), descriptor, DialogModes.NO);
}
///// MAIN SCRIPT EXECUTION /////
try {
if (app.documents.length > 0) {
var dlg = createDialog();
// CSV selection button
dlg.mainPanel.csvFileBtn.onClick = function () {
var csvFileRef = File.openDialog("Select CSV file:");
if (csvFileRef !== null) {
dlg.mainPanel.csvFilePath.text = csvFileRef.fsName;
}
};
// Output folder selection button
dlg.mainPanel.outputFolderBtn.onClick = function () {
var saveFolder = Folder.selectDialog("Select the output folder to save the files to:");
if (saveFolder !== null) {
dlg.mainPanel.outputFolderPath.text = saveFolder.fsName;
}
};
// Generate the dialog
if (dlg.show() === 1) {
// File and folder variables
var csvFileRef = new File(dlg.mainPanel.csvFilePath.text);
var saveFolder = new Folder(dlg.mainPanel.outputFolderPath.text);
var selectedFormat = dlg.mainPanel.formatList.selection.text;
var selectedSuffixOption = dlg.mainPanel.suffixList.selection.index;
// Import the data sets from the CSV file
fileImportDataSets(csvFileRef);
// Variables for the loop
var datasetNames = getDataSetNames(csvFileRef);
var fileCounter = 0;
var originalDocName = app.activeDocument.name.replace(/\.[^\.]+$/, ''); // Capture the base name once
// Loop through the dataset names and save each file
for (var i = 1; i < datasetNames.length; i++) {
applyDataSet(datasetNames[i]);
// Define suffix based on selection
var suffix = '';
// First column in CSV
if (selectedSuffixOption === 0) {
suffix = getDataSetNames(csvFileRef)[i].replace(/.*\//, '').replace(/\.[^\.]+$/, '');
// 4-digit padded set number
} else if (selectedSuffixOption === 1) {
suffix = paddedSetNo(i);
}
// Construct the filename
var fileName = originalDocName + separator + suffix;
var extension = '';
if (selectedFormat === 'JPEG') {
extension = '.jpg';
} else if (selectedFormat === 'PNG') {
extension = '.png';
} else if (selectedFormat === 'WEBP') {
extension = '.webp';
} else if (selectedFormat === 'TIFF') {
extension = '.tif';
} else if (selectedFormat === 'PSB') {
extension = '.psb';
}
// Save folder and file name
var saveFile = new File(saveFolder + "/" + fileName + extension);
// Save the file with the selected format
if (selectedFormat === 'JPEG') {
app.activeDocument.saveAs(saveFile, jpegSaveOptions(), true, Extension.LOWERCASE);
} else if (selectedFormat === 'PNG') {
app.activeDocument.saveAs(saveFile, pngSaveOptions(), true, Extension.LOWERCASE);
} else if (selectedFormat === 'WEBP') {
saveWebP(saveFile);
} else if (selectedFormat === 'TIFF') {
saveTIFF(saveFile);
} else if (selectedFormat === 'PSB') {
savePSB(saveFile);
}
// Increment the file counter
fileCounter++;
}
// End of script
app.beep();
alert(fileCounter + " " + selectedFormat + " files have been saved to:" + "\n" + saveFolder.fsName);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
} else {
alert('A template file must be open before running this script...');
}
} catch (error) {
alert(error + ', Line: ' + error.line);
}
Copy the code text to the clipboard
Open a new blank file in a plain-text editor (not in a word processor)
Paste the code in
Save as a plain text format file – .txt
Rename the saved file extension from .txt to .jsx
Install or browse to the .jsx file to run (see below):
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html
... View more
Community Expert
in Photoshop ecosystem Discussions
‎Mar 04, 2025
12:33 AM
1 Upvote
‎Mar 04, 2025
12:33 AM
1 Upvote
The text file encoding may not be correct for images using non-standard characters.
Can you upload the .csv file? You might need to rename it .txt for the forum software.
... View more
‎Mar 04, 2025
12:29 AM
Actions have always worked this way, you would need a script to store and retrieve a folder path for saving.
... View more
Community Expert
in Photoshop ecosystem Discussions
‎Mar 04, 2025
12:15 AM
2 Upvotes
‎Mar 04, 2025
12:15 AM
2 Upvotes
@Bojan Živković - As far as I know, actions record the specific mask details for that individual image, so scripting this has the same limitations.
Actions are the "old school" way of batch processing inside Photoshop. The Camera Raw filter isn't always going to play nicely with Actions or scripts.
@Mike35315067k4t9 - Do this outside of Photoshop, directly in the Adobe Camera Raw plugin on RGB JPEG/TIFF files, where a preset using AI masks works correctly when batch processing the applied settings from one image to all selected images in the filmstrip. If one has Lightroom then that's another option.
... View more
Community Expert
in Photoshop ecosystem Discussions
‎Mar 03, 2025
06:10 PM
1 Upvote
‎Mar 03, 2025
06:10 PM
1 Upvote
Actions have always recorded an absolute path from the recording system, and optionally a filename as well:
If running the action in interactive "modal" mode on a single open image, you can change the filename and location.
If running the action via the automate > batch command, then there's a checkbox to "override action save options" so that the recorded path and or name aren't used (otherwise the batch would overwrite itself).
... View more
‎Mar 02, 2025
04:10 PM
You're welcome.
... View more
Community Expert
in Photoshop ecosystem Discussions
‎Mar 02, 2025
02:49 PM
1 Upvote
‎Mar 02, 2025
02:49 PM
1 Upvote
I have been extending the original code from the late Mike Hale here:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/using-datasets/td-p/2665594/page/2
I am currently using a confirm dialog for the user to OK to run the script, which relies on them knowing that the file already has Variables/Data Sets defined.
Ideally, the script would check for the existence of Data Sets and terminate if none were found.
Unfortunately, the action manager code is beyond me, so I was wondering if anyone knew how to check for this.
... View more
Community Expert
in Photoshop ecosystem Discussions
‎Mar 02, 2025
01:21 PM
2 Upvotes
‎Mar 02, 2025
01:21 PM
2 Upvotes
@powerful_Zephyr5EF9 – Have you downloaded and installed the ScriptingListener plugin?
https://helpx.adobe.com/au/photoshop/kb/downloadable-plugins-and-content.html
This is necessary for things the basic Photoshop ExtendScript DOM does not cover.
Doing so would give you something like this:
var idcolorRange = stringIDToTypeID( "colorRange" );
var desc376 = new ActionDescriptor();
var idfuzziness = stringIDToTypeID( "fuzziness" );
desc376.putInteger( idfuzziness, 10 );
var idcolors = stringIDToTypeID( "colors" );
var idcolors = stringIDToTypeID( "colors" );
var idskinTone = stringIDToTypeID( "skinTone" );
desc376.putEnumerated( idcolors, idcolors, idskinTone );
var idcolorModel = stringIDToTypeID( "colorModel" );
desc376.putInteger( idcolorModel, 0 );
executeAction( idcolorRange, desc376, DialogModes.NO );
var idcopyToLayer = stringIDToTypeID( "copyToLayer" );
executeAction( idcopyToLayer, undefined, DialogModes.NO );
... View more
‎Mar 01, 2025
07:59 PM
@richardg52861327
Your post has already been moved, no need to repost.
https://community.adobe.com/t5/photoshop-ecosystem/ct-p/ct-photoshop
... View more
‎Mar 01, 2025
07:38 PM
Is it possible to randomise parameters that aren't integers? For example, the Neon Glow filter that has a parameter that takes a color. Is this something that could be randomised as well
Yes, the Red/Green/Blue values are just three separate integers between 0-255 in value, so easy enough with the code previously provided as a guide.
Another example is the Rough Pastels filter which has a parameter titled scaling that takes in a percent value ranging from 50% to 200%. Could this type of parameter be randomised?
By @ugonnaa21431338
The scaling value is still an integer, so easy enough with the code previously provided as an example.
What will be more challenging are parameters using specific names, such as the texture and the light direction parameters.
Here's an example of randomising the texture, which is based on an array of four names, rather than integers:
var textures = ["texTypeBrick", "texTypeBurlap", "texTypeCanvas", "texTypeSandstone"];
var randomTexture = textures[Math.floor(Math.random() * textures.length)];
alert(randomTexture);
GEfc_roughPastels(6, 4, randomTexture, 111, 20, false);
function GEfc_roughPastels(strokeLength, strokeDetail, theTexture, scaling, relief, invertTexture) {
var c2t = function (s) {
return app.charIDToTypeID(s);
};
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
descriptor.putEnumerated(c2t("GEfk"), c2t("GEft"), s2t("roughPastels"));
descriptor.putInteger(s2t("strokeLength"), strokeLength);
descriptor.putInteger(s2t("strokeDetail"), strokeDetail);
descriptor.putEnumerated(s2t("textureType"), s2t("textureType"), s2t(theTexture));
descriptor.putInteger(s2t("scaling"), scaling);
descriptor.putInteger(s2t("relief"), relief);
descriptor.putEnumerated(s2t("lightDirection"), s2t("lightDirection"), s2t("lightDirBottomRight"));
descriptor.putBoolean(s2t("invertTexture"), invertTexture);
executeAction(c2t("GEfc"), descriptor, DialogModes.NO);
}
You can remove or //comment out the alert line, it's just there so that you can see what is going on.
A similar approach could be used for the light direction, which has eight parameters.
This project will be a labour of love... Good luck!
... View more
‎Mar 01, 2025
07:22 PM
Using your example of Poster Edges, here is the raw ScriptListener recording:
var idGEfc = charIDToTypeID( "GEfc" );
var desc272 = new ActionDescriptor();
var idGEfk = charIDToTypeID( "GEfk" );
var idGEft = charIDToTypeID( "GEft" );
var idposterEdges = stringIDToTypeID( "posterEdges" );
desc272.putEnumerated( idGEfk, idGEft, idposterEdges );
var idedgeThickness = stringIDToTypeID( "edgeThickness" );
desc272.putInteger( idedgeThickness, 3 );
var idedgeIntensity = stringIDToTypeID( "edgeIntensity" );
desc272.putInteger( idedgeIntensity, 2 );
var idposterization = stringIDToTypeID( "posterization" );
desc272.putInteger( idposterization, 1 );
executeAction( idGEfc, desc272, DialogModes.NO );
Here is how the raw recording looks using the CleanSL script:
GEfc(3, 2, 1);
function GEfc(edgeThickness, edgeIntensity, posterization) {
var c2t = function (s) {
return app.charIDToTypeID(s);
};
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
descriptor.putEnumerated(c2t("GEfk"), c2t("GEft"), s2t("posterEdges"));
descriptor.putInteger(s2t("edgeThickness"), edgeThickness);
descriptor.putInteger(s2t("edgeIntensity"), edgeIntensity);
descriptor.putInteger(s2t("posterization"), posterization);
executeAction(c2t("GEfc"), descriptor, DialogModes.NO);
}
Here I have manually created a function and function call and manually replaced the hard-coded values with variable names for the parameters. This is without using the CleanSL script:
galleryEffects_PosterEdges(3, 2, 1);
function galleryEffects_PosterEdges(thicknessValue, intensityValue, posterizationValue) {
var idGEfc = charIDToTypeID("GEfc");
var desc272 = new ActionDescriptor();
var idGEfk = charIDToTypeID("GEfk");
var idGEft = charIDToTypeID("GEft");
var idposterEdges = stringIDToTypeID("posterEdges");
desc272.putEnumerated(idGEfk, idGEft, idposterEdges);
var idedgeThickness = stringIDToTypeID("edgeThickness");
desc272.putInteger(idedgeThickness, thicknessValue); // Replace the integer with a variable
var idedgeIntensity = stringIDToTypeID("edgeIntensity");
desc272.putInteger(idedgeIntensity, intensityValue); // Replace the integer with a variable
var idposterization = stringIDToTypeID("posterization");
desc272.putInteger(idposterization, posterizationValue); // Replace the integer with a variable
executeAction(idGEfc, desc272, DialogModes.NO);
}
Next, you would then need to work out what the valid range of values are for each parameter from the user interface... Finally, you would then add in the variables to create the random values for each parameter and replace the numerical values with the variable names as I previously did with my initial example.
... View more
‎Mar 01, 2025
06:01 PM
It's rarely that easy, the names are not always logical or obvious. To self serve, you're going to need to install the following:
ScriptingListener plugin from Adobe:
https://helpx.adobe.com/au/photoshop/kb/downloadable-plugins-and-content.html
Although not strictly necessary, I highly recommend the CleanSL script to refactor and create functions from the basic code recordings:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/clean-sl/td-p/9358420
https://github.com/rendertom/Clean-SL
... View more
‎Mar 01, 2025
05:40 PM
You need a separate function for each separate filter. Each function would have random parameters that may or may not be shared with other filters.
All of the functions could be in the one script, with function calls as necessary to run specific randomised filters. Or they could all be separate self contained scripts, each with a unique function and function call.
It depends on the parameters as to how one would code the randomised values. Some would be easier than others.
Just how many different filters are you looking at randomising? It could take anywhere from a couple of minutes to much longer, per filter to create the randomised parameters, not including testing and bug fixes.
This can easily be a black hole for time.
... View more
Community Expert
in Photoshop ecosystem Discussions
‎Mar 01, 2025
04:20 PM
1 Upvote
‎Mar 01, 2025
04:20 PM
1 Upvote
Here is a visual example of the how the Photocopy filter would be scripted, using fixed parameters. These fixed parameters would need to be replaced with variables from random generators.
And here is an example of how this would be scripted:
var photocopyRandomDetail = Math.floor(Math.random() * 24) + 1; // Random integer between 1-24
var photocopyRandomDarken = Math.floor(Math.random() * 50) + 1; // Random integer between 1-50
GEfc_photocopy(photocopyRandomDetail, photocopyRandomDarken);
function GEfc_photocopy(detail, darken) {
var c2t = function (s) {
return app.charIDToTypeID(s);
};
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
descriptor.putEnumerated(c2t("GEfk"), c2t("GEft"), s2t("photocopy"));
descriptor.putInteger(s2t("detail"), detail);
descriptor.putInteger(s2t("darken"), darken);
executeAction(c2t("GEfc"), descriptor, DialogModes.NO);
}
Note: I purposely chose a simple example. Some of the filters use parameters which are not simple integers.
... View more
‎Mar 01, 2025
03:58 PM
Please provide before and after examples.
... View more
Community Expert
in Photoshop ecosystem Discussions
‎Mar 01, 2025
03:51 PM
1 Upvote
‎Mar 01, 2025
03:51 PM
1 Upvote
@ugonnaa21431338
The easy and short answer is yes.
The harder and longer answer is that it depends. Your question is too generic, it comes down to specifics.
The Filter Gallery has six main groups.
Within each group there are a variable number of separate filters.
Each filter has different parameters, that vary in count and applicable values.
Finally, multiple filters and their parameters can be combined in a single pass by using the + sign to combine their results based on the order of operations
Bottom line is that you need to be very specific... For example:
* How many total filters do you wish to randomise?
* If there were 3 filters in total, should the selection of one of the 3 filters be randomised?
* Once the script runs a specific filter, is it every parameter that needs to be randomised for each filter, or are there only specific parameters within a given filter that require randomisation?
... View more
Community Expert
in Photoshop ecosystem Discussions
‎Mar 01, 2025
02:59 PM
1 Upvote
‎Mar 01, 2025
02:59 PM
1 Upvote
I'm not sure if I'm understanding, however, there is the Image > Duplicate command.
... View more
‎Mar 01, 2025
01:58 AM
This is the challenge of using Photoshop or rasterize presumably live text/vector content.
You can try grayscale mode if colour isn't critical which is 1/3 the file size of RGB.
Even better would be bitmap mode, which would allow higher resolution and better lossless compression, however, I'm not sure if this mode is supported by PDF Presentation to create a multi page PDF.
A native PDF tool would be better for the task.
... View more
‎Mar 01, 2025
01:52 AM
You can use the shift key modifier when dragging to "pin register" them together if they are the same pixel dimensions (middle centre aligned).
You can also use the Layer > Duplicate command to dupe selected layer/s or groups between documents.
... View more
‎Feb 28, 2025
08:14 PM
2 Upvotes
I don't think I've ever needed a blank document the size of the clipboard. I very frequently want the clipboard to open in Photoshop. Why should I enter a keystroke to avoid something I never want?
@Semaphoric
I was specifically replying to the comment regarding GIMP having a "New Layer from Clipboard" when Photoshop doesn't. This is an extension of the OT where it was about a new document from the clipboard.
Creating a new layer from the clipboard is as simple as a single paste command, so is this just semantics? Do we really need a new, separate menu item to paste clipboard content as a new layer when we can just paste the clipboard content using an existing single command?
Creating a new document from the clipboard takes multiple steps, which makes more sense for a new command, outside of DIY actions/scripts which can be triggered using a single command.
... View more
‎Feb 28, 2025
07:21 PM
Hello Stephen,
Thanks for your reply. When running the crop command as a recorded action is missing its crop handles in every verson of Photoshop after version 25.11. Zooming, showing extras, or any other movements are not available when running actions. Please consider that the crop command is not the only command running in the recorded script.
By @marcdwelis
Well, I naturally assumed that you had the modal control active on the action step for an interactive crop.
Anyway, I downloaded Photoshop 2025 and had no problems with cropping with a modal control active, the handles were there.
I played around with the gear/cog icon and turned classic mode on and off and crop shield etc... Then I lost the handles!
Resetting prefs on quit didn't fix things.
Running the modal action step, and going to the gear/cog icon and turning classic mode on and off and crop shield on and off etc. didn't fix anything.
I exited the action.
Next, I manually used the crop tool without using the action, again playing with the various options and my crop handles returned! The next time I ran the modal action, it was reset and the handles were again visible.
Hope this works for you!
... View more
‎Feb 28, 2025
06:36 PM
1 Upvote
@Raster_Eyes wrote:
So is New Layer from Clipboard.
In all seriousness, what is wrong with Ctrl/Cmd + V to paste in a new layer? It's a single command.
With a new doc from clipboard, it's Ctrl/Cmd + N plus OK plus Ctrl/Cmd + V – so three steps minimum, perhaps four or more if you want to clean up the layers.
I created a script for new document from keyboard as there were multiple steps, so apart from paste, what would new layer from clipboard actually need? Revealing the canvas if the new layer content was larger? Aligning the new layer to the canvas if the default upper left wasn't desired? What else?
... View more
‎Feb 28, 2025
06:21 PM
Done. Thank you so much for everything.
By @Suraiya A
Thank you and you're welecome!
... View more
Community Expert
in Photoshop ecosystem Discussions
‎Feb 28, 2025
04:56 PM
1 Upvote
‎Feb 28, 2025
04:56 PM
1 Upvote
Hard to comment as the image upload is incomplete. One possible "out of the box" option:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/jpeg-with-outline-path-to-transparent-png-files-conversion/m-p/13055741#U13071607
https://www.marspremedia.com/download-confirmed?asset=batch-web-images.zip
https://www.marspremedia.com/software/photoshop/batch-web-images
https://m.youtube.com/watch?v=Fes9ApyIMhM
Otherwise, record an action using Select Subject and adding a mask or otherwise clearing the background of a floating layer, then run via Batch, Image Processor etc.
... View more