/* * Description: An Adobe Photoshop script that converts multiple AI files into the native PSD file format. * Tested on Photoshop CS4 and Photoshop 2024 Windows. * License: This work is licensed under a Creative Commons Attribution-NoDerivatives 4.0 International License. (https://creativecommons.org/licenses/by-nd/4.0/) * Copyright (c) 2024, Michel Simons * http://www.no-nonsens.nl * 2.18 October 2024 * 1.05 March 11th 2012 * 1.04 February 21th 2012 You are free to: Share copy and redistribute the material in any medium or format for any purpose, even commercially. The licensor cannot revoke these freedoms as long as you follow the license terms. Under the following terms: Attribution: You must give appropriate credit , provide a link to the license, and indicate if changes were made . You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. NoDerivatives: If you remix, transform, or build upon the material, you may not distribute the modified material. No additional restrictions: You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. Notices: You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation. No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material. */ // ******************************************************************************************************** // ** ** // ** To Do list ** // ** ** // ******************************************************************************************************** // // - check error checking and make more uniform error-messaging. // // ******************************************************************************************************** // ** ** // ** Known issues ** // ** ** // ******************************************************************************************************** // // - // // ******************************************************************************************************** // ** ** // ** initialize variables and start dialog ** // ** ** // ******************************************************************************************************** #target photoshop if (app.name != "Adobe Photoshop") { alert ('This script is created for Adobe Photoshop, it is not developed for or tested on ' + app.name + '. Results can be unexpected.' ); } var ScriptVersion = "2.18"; var ErrorList = []; var FileBasePath = ""; // default output folder var pdfOpenOptions = new PDFOpenOptions(); var epsOpenOptions = new EPSOpenOptions(); var svgOpenOptions = {resolution: 300, colorMode: 'CMYK', bitMode: 8}; // ******************************************************************************************************** // ** ** // ** helper function to open SVG files ** // ** source code derived from ChatGTP ** // ** ** // ******************************************************************************************************** // Step 1: open document function openSVGWithOptions(filePath) { var processResolution = svgOpenOptions.resolution; // Step 1: Open the SVG file var idOpn = charIDToTypeID( "Opn " ); var desc3 = new ActionDescriptor(); var iddontRecord = stringIDToTypeID( "dontRecord" ); desc3.putBoolean( iddontRecord, false ); var idforceNotify = stringIDToTypeID( "forceNotify" ); desc3.putBoolean( idforceNotify, true ); var idnull = charIDToTypeID("null"); desc3.putPath(idnull, filePath); var idAs = charIDToTypeID( "As " ); var desc4 = new ActionDescriptor(); var idsvgFormat = stringIDToTypeID( "svgFormat" ); desc3.putObject( idAs, idsvgFormat, desc4 ); var idDocI = charIDToTypeID( "DocI" ); desc3.putInteger( idDocI, 219 ); executeAction( idOpn, desc3, DialogModes.NO ); // Step 2: Set the resolution (DPI) var doc = app.activeDocument; app.activeDocument.resizeImage(undefined, undefined, processResolution, ResampleMethod.NONE); } // ******************************************************************************************************** // ** ** // ** helper function to remove duplicate items from the ListBox ** // ** source code derived from ChatGTP ** // ** ** // ******************************************************************************************************** function removeDuplicates() { var uniqueFiles = {}; // Object to track unique files by full path for (var i = 0; i < ListBox1.items.length; i++) { var filePath = ListBox1.items[i].fullPath; if (!uniqueFiles[filePath]) { uniqueFiles[filePath] = { fileName: ListBox1.items[i].text, fullPath: filePath }; } } // Clear the ListBox and repopulate with unique items ListBox1.removeAll(); for (var filePath in uniqueFiles) { var listItem = ListBox1.add("item", uniqueFiles[filePath].fileName); listItem.fullPath = uniqueFiles[filePath].fullPath; } } // ******************************************************************************************************** // ** ** // ** helper function to sort ListBox items A to Z ** // ** source code derived from ChatGTP ** // ** ** // ******************************************************************************************************** function sortArray() { // Retrieve all items from the ListBox var itemsArray = []; for (var i = 0; i < ListBox1.items.length; i++) { itemsArray.push({ fileName: ListBox1.items[i].text, // Store the displayed file name fullPath: ListBox1.items[i].fullPath // Store the full path }); } // Sort items by the fileName property (A to Z) itemsArray.sort(function(a, b) { return a.fileName.localeCompare(b.fileName); }); // Clear the ListBox and repopulate with sorted items ListBox1.removeAll(); for (var i = 0; i < itemsArray.length; i++) { var listItem = ListBox1.add("item", itemsArray[i].fileName); listItem.fullPath = itemsArray[i].fullPath; // Restore the full path } } // ******************************************************************************************************** // ** ** // ** helper function to add selected files to the file list dialog ** // ** ** // ******************************************************************************************************** function AddFilesToDialog() { try { var selectedFiles = File.openDialog("Add files to process", "Vector files:*.ai;*.pdf;*.svg;*.eps,Illustrator AI files:*.ai,Acrobat PDF files:*.pdf,Scalable Vector Format:*.svg, Encapsulated Postscript:*.eps", true); if (selectedFiles && selectedFiles.length > 0) { for (var i = 0; i < selectedFiles.length; i++) { var fileName = selectedFiles[i].name; // Extract file name from the path var decodedFileName = decodeURIComponent(fileName); // Remove URL encoding var listItem = ListBox1.add("item", decodedFileName); // Add file name to the ListBox listItem.fullPath = selectedFiles[i].fsName; // Store full file path in custom property } } removeDuplicates(); sortArray(); } catch(err) { alert( err.message ); ErrorList.push ( err ); } if ((ExportEdit.text.length == 0) && selectedFiles && selectedFiles.length > 0) { var commonFolderPath = selectedFiles[0].parent; FileBasePath = commonFolderPath.fsName.toString(); ExportEdit.text = FileBasePath; } if (ListBox1.items.length > 0) {button_convert.enabled = true;} else {button_convert.enabled = false;} ProgressLabel.text = ListBox1.items.length + ' files are waiting for conversion.'; scriptdialog.update; } // ******************************************************************************************************** // ** ** // ** helper function to remove selected files from the file list dialog ** // ** ** // ******************************************************************************************************** function removeFilesFromDialog() { try { var selectedItems = ListBox1.selection; if (selectedItems) { // Find the indices of the selected items var selectedIndices = []; for (var i = 0; i < ListBox1.items.length; i++) { if (ListBox1.items[i].selected) { selectedIndices.push(i); } } // Remove items by index in reverse order (to avoid index shifting) selectedIndices.sort(function(a, b) { return b - a; }); for (var i = 0; i < selectedIndices.length; i++) { ListBox1.remove(selectedIndices[i]); } } } catch(err) { alert( err.message ); ErrorList.push ( err ); } if (ListBox1.items.length > 0) {button_convert.enabled = true;} else {button_convert.enabled = false;} ProgressLabel.text = ListBox1.items.length + ' files are waiting for conversion.'; scriptdialog.update; } // ******************************************************************************************************** // ** ** // ** helper function to clear all items in the listbox ** // ** ** // ******************************************************************************************************** function clearFilesfromDialog() { try { ListBox1.removeAll(); } catch(err) { alert( err.message ); ErrorList.push ( err ); } if (ListBox1.items.length > 0) {button_convert.enabled = true;} else {button_convert.enabled = false;} ProgressLabel.text = ListBox1.items.length + ' files are waiting for conversion.'; scriptdialog.update; } // ******************************************************************************************************** // ** ** // ** helper function to get the file extension listbox ** // ** source code derived from ChatGTP ** // ** ** // ******************************************************************************************************** function getFileExtension(file) { var filename; // Check if the input is a File object if (file instanceof File) { // Use the File object's name property filename = file.name; } else if (typeof file === 'string') { // If it's a string, assume it's a filename filename = file; } else { // Invalid input, return empty string return ''; } // Find the last index of the dot in the filename var lastDotIndex = filename.lastIndexOf('.'); // If no dot is found, return an empty string if (lastDotIndex === -1) { return ''; } // Get the substring after the last dot and convert to lowercase var extension = filename.substring(lastDotIndex + 1).toLowerCase(); return extension; } // ******************************************************************************************************** // ** ** // ** helper function to remove the file extension from a file name ** // ** source code derived from ChatGTP ** // ** ** // ******************************************************************************************************** function removeFileExtension(fileName) { // Find the last dot in the file name var lastDotIndex = fileName.lastIndexOf('.'); // If there's no dot, return the file name as is if (lastDotIndex === -1) { return fileName; // No extension found } // Return the file name without the extension return fileName.substring(0, lastDotIndex); } // ******************************************************************************************************** // ** ** // ** helper function to split a string into a path and filename ** // ** source code derived from ChatGTP ** // ** ** // ******************************************************************************************************** function splitPathAndFilename(filePath) { // Find the last backslash in the file path var lastBackslashIndex = filePath.lastIndexOf('\\'); // If there's no backslash, we assume it's only the filename if (lastBackslashIndex === -1) { return { folderPath: '', fileName: filePath }; } // Split into folder path and filename (including extension) var folderPath = filePath.substring(0, lastBackslashIndex + 1); // Folder path (include the backslash) var fileName = filePath.substring(lastBackslashIndex + 1); // File name (after the last backslash) return { folderPath: folderPath, fileName: fileName }; } // ******************************************************************************************************** // ** ** // ** helper function change file extension ** // ** source code derived from ChatGTP ** // ** ** // ******************************************************************************************************** function changeFileExtension(filePath, newExtension) { // Find the last dot in the file path var lastDotIndex = filePath.lastIndexOf('.'); // If there's no dot or it's part of the directory, we don't change anything if (lastDotIndex === -1 || filePath.lastIndexOf('\\') > lastDotIndex) { return filePath; // Return the original file path if there's no extension } // Replace the current extension with the new one var newFilePath = filePath.substring(0, lastDotIndex) + '.' + newExtension; return newFilePath; } // ******************************************************************************************************** // ** ** // ** import and rasterize AI or PDF file ** // ** ** // ******************************************************************************************************** function importFromAI(s, IncrementalValue) { ProgressLabel.text = 'Rasterizing file ' + (s + 1) + ' out of ' + ListBox1.items.length + ' files. [ ' + ListBox1.items[s].text + ' ]'; ProgressProgressBar.value = ProgressProgressBar.value + IncrementalValue; scriptdialog.update(); // try loading file into photoshop try { var item = ListBox1.items[s]; var fileToOpen = new File (item.fullPath); // get file extension var extension = getFileExtension(fileToOpen); if (extension == 'ai' || extension == 'pdf') {open(fileToOpen, pdfOpenOptions);} if (extension == 'svg') {openSVGWithOptions(fileToOpen);} if (extension == 'eps') {open(fileToOpen, epsOpenOptions);} app.refresh(); } catch(err) { alert (err.message); ErrorList.push ( err ); } // try to set the document layer name conform the file name try { var TheFileName = item.fullPath; // the ai or pdf filename for the current item var StrippedPathFileNameA = splitPathAndFilename(TheFileName); // split var in path and filename var StrippedPathFileNameB = StrippedPathFileNameA.fileName; // return filename var StrippedPathFileNameC = removeFileExtension(StrippedPathFileNameB);// return extension app.activeDocument.activeLayer.name = StrippedPathFileNameC; app.refresh(); } catch(err) { alert(err.message); ErrorList.push ( err ); } } // ******************************************************************************************************** // ** ** // ** check if the docuement can be saved as psd or psb file ** // ** ** // ******************************************************************************************************** function CheckNewFormat() { var doc = app.activeDocument; // Get the width and height in pixels var width = doc.width.as('px'); // Get width in pixels var height = doc.height.as('px'); // Get height in pixels // Get number of layers in the document var numLayers = doc.layers.length; // Get the bit depth and bytes per pixel var bytesPerPixel; switch (doc.bitsPerChannel) { case BitsPerChannelType.ONE: // 1-bit (usually for bitmap) bytesPerPixel = 1 / 8; // 1 bit per pixel break; case BitsPerChannelType.EIGHT: // 8-bit per channel bytesPerPixel = 3; // 3 bytes for RGB if (doc.mode == DocumentMode.CMYK) { bytesPerPixel = 4; // 4 bytes for CMYK } break; case BitsPerChannelType.SIXTEEN: // 16-bit per channel bytesPerPixel = 6; // 6 bytes for RGB if (doc.mode == DocumentMode.CMYK) { bytesPerPixel = 8; // 8 bytes for CMYK } break; case BitsPerChannelType.THIRTYTWO: // 32-bit per channel bytesPerPixel = 12; // 12 bytes for RGB if (doc.mode == DocumentMode.CMYK) { bytesPerPixel = 16; // 16 bytes for CMYK } break; default: throw new Error("Unsupported bit depth"); } // Calculate the base size of the image (width x height x bytes per pixel) var baseSize = width * height * bytesPerPixel; // Estimate the file size by considering layers // Typically, each layer adds roughly the base size, so we multiply by the number of layers. var estimatedFileSize = baseSize * numLayers; // Convert estimated file size to gigabytes (GB) var estimatedFileSizeGB = estimatedFileSize / (1024 * 1024 * 1024); // 2GB PSD file size limit var fileSizeLimitGB = 2; if (width <= 30000 && height <= 30000 && estimatedFileSizeGB <= fileSizeLimitGB) { // Save as PSD FileTypeDetect = "psd"; } else { // Save as PSB FileTypeDetect = "psb"; } return (FileTypeDetect); } // ******************************************************************************************************** // ** ** // ** create actionDescriptor for saving in the PSB file format ** // ** thanks to William Campbell || https://www.youtube.com/watch?v=F3fPl6d7jz0 ** // ** ** // ******************************************************************************************************** function saveAsPsb(fullPath) { var desc1 = new ActionDescriptor(); var desc2 = new ActionDescriptor(); desc1.putObject(charIDToTypeID('As '), stringIDToTypeID("largeDocumentFormat"), desc2); desc1.putPath(charIDToTypeID('In '), fullPath); desc1.putInteger(charIDToTypeID('DocI'), app.activeDocument.id); // Use dynamic document ID desc1.putBoolean(charIDToTypeID('LwCs'), true); try { executeAction(charIDToTypeID('save'), desc1, DialogModes.NO); } catch (err) { alert("Error saving PSB: " + err.message); ErrorList.push ( err ); } } // ******************************************************************************************************** // ** ** // ** save current document as psd file ** // ** ** // ******************************************************************************************************** function saveAsPSD(s, IncrementalValue) { // get the current file name try { var item = ListBox1.items[s]; var TheFileNameItem = item.fullPath; // the ai or pdf filename for the current item var TheFileName = TheFileNameItem.toString(); // to regular string var StrippedPathFileNameA = splitPathAndFilename(TheFileName); // split var in path and filename var StrippedPathFileNameB = StrippedPathFileNameA.fileName; // return filename // can we save the document as psd or do we need to switch to the psb file format? var FileTypeDetect = CheckNewFormat(); var NewFileName = changeFileExtension(StrippedPathFileNameB, FileTypeDetect); ProgressLabel.text = 'Saving file ' + (s + 1) + ' out of ' + ListBox1.items.length + ' files. [ ' + NewFileName + ' ]'; ProgressProgressBar.value = ProgressProgressBar.value + IncrementalValue; scriptdialog.update(); } catch(err) { alert (err.message); ErrorList.push ( err ); } // construct new path and filename try { var myPath = new Folder ( Folder (FileBasePath) ); var myFile = new File ( myPath + "/" + NewFileName ); } catch(err) { alert (err.message); ErrorList.push ( err ); } try { var doc = app.activeDocument; if (FileTypeDetect == "psd") { var psdFile = new File( myFile ); var psdSaveOptions = new PhotoshopSaveOptions(); psdSaveOptions.embedColorProfile = true; psdSaveOptions.alphaChannels = true; psdSaveOptions.annotations = true; psdSaveOptions.layers = true; doc.saveAs( psdFile, psdSaveOptions, false, Extension.LOWERCASE ); doc.close(SaveOptions.DONOTSAVECHANGES); } if (FileTypeDetect == "psb") { var psbFile = new File( myFile ); // Also OK if file object omits the file extension; function adds it. saveAsPsb(psbFile); doc.close(SaveOptions.DONOTSAVECHANGES); } app.refresh(); } catch(err) { alert (err.message); ErrorList.push ( err ); doc.close(SaveOptions.DONOTSAVECHANGES); } } // ******************************************************************************************************** // ** ** // ** set no choise options ** // ** ** // ******************************************************************************************************** function noChoiceOptions() { //set units to pixels app.preferences.rulerUnits = Units.PIXELS; //avoid displaying dialog boxes => All , ERROR , NO app.displayDialogs = DialogModes.NO; //define the pdf options for opening the document pdfOpenOptions.supressWarnings = true; epsOpenOptions.supressWarnings = true; pdfOpenOptions.constrainProportions = true; epsOpenOptions.constrainProportions = true; } // ******************************************************************************************************** // ** ** // ** set choise options for PDF/AI and EPS ** // ** ** // ******************************************************************************************************** function ChoiceOptions() { // CropToType switch(myTrimCropSettings.selection.index) { case 0: pdfOpenOptions.cropPage = CropToType.BOUNDINGBOX; break; case 1: pdfOpenOptions.cropPage = CropToType.MEDIABOX; break; case 2: pdfOpenOptions.cropPage = CropToType.CROPBOX; break; case 3: pdfOpenOptions.cropPage = CropToType.BLEEDBOX; break; case 4: pdfOpenOptions.cropPage = CropToType.TRIMBOX; break; case 5: pdfOpenOptions.cropPage = CropToType.ARTBOX; break; } // Resolution switch(myDPISettings.selection.index) { case 0: pdfOpenOptions.resolution = 72; epsOpenOptions.resolution = 72; svgOpenOptions.resolution = 72; break; case 1: pdfOpenOptions.resolution = 100; epsOpenOptions.resolution = 100; svgOpenOptions.resolution = 100; break; case 2: pdfOpenOptions.resolution = 150; epsOpenOptions.resolution = 150; svgOpenOptions.resolution = 150; break; case 3: pdfOpenOptions.resolution = 200; epsOpenOptions.resolution = 200; svgOpenOptions.resolution = 200; break; case 4: pdfOpenOptions.resolution = 300; epsOpenOptions.resolution = 300; svgOpenOptions.resolution = 300; break; case 5: pdfOpenOptions.resolution = 600; epsOpenOptions.resolution = 600; svgOpenOptions.resolution = 600; break; case 6: pdfOpenOptions.resolution = 1200; epsOpenOptions.resolution = 1200; svgOpenOptions.resolution = 1200; break; } // OpenDocumentMode switch(myColorSettings.selection.index) { case 0: pdfOpenOptions.mode = OpenDocumentMode.GRAYSCALE; epsOpenOptions.mode = OpenDocumentMode.GRAYSCALE; svgOpenOptions.colorMode = 'GRAYSCALE'; break; case 1: pdfOpenOptions.mode = OpenDocumentMode.RGB; epsOpenOptions.mode = OpenDocumentMode.RGB; svgOpenOptions.colorMode = 'RGB'; break; case 2: pdfOpenOptions.mode = OpenDocumentMode.CMYK; epsOpenOptions.mode = OpenDocumentMode.CMYK; svgOpenOptions.colorMode = 'CMYK'; break; case 3: pdfOpenOptions.mode = OpenDocumentMode.LAB; epsOpenOptions.mode = OpenDocumentMode.LAB; svgOpenOptions.colorMode = 'LAB'; break; } // BitDepth switch(myBitsSettings.selection.index) { case 0: pdfOpenOptions.bitsPerChannel = BitsPerChannelType.EIGHT; svgOpenOptions.bitMode = 8; break; case 1: pdfOpenOptions.bitsPerChannel = BitsPerChannelType.SIXTEEN; svgOpenOptions.bitMode = 16; break; } // Anti Alias switch(myAntiAliasedSettings.value) { case 0: pdfOpenOptions.antiAlias = false; epsOpenOptions.antiAlias = flase; break; case 1: pdfOpenOptions.antiAlias = true; epsOpenOptions.antiAlias = true; break; } } // ******************************************************************************************************** // ** ** // ** check for correct color model and if required adjust ** // ** ** // ******************************************************************************************************** function checkColorModel() { var processColorMode = svgOpenOptions.colorMode; var doc = app.activeDocument; switch (processColorMode.toLowerCase()) { case 'rgb': if (doc.mode != DocumentMode.RGB) { doc.changeMode(ChangeMode.RGB); } break; case 'cmyk': if (doc.mode != DocumentMode.CMYK) { doc.changeMode(ChangeMode.CMYK); } break; case 'grayscale': if (doc.mode != DocumentMode.GRAYSCALE) { doc.changeMode(ChangeMode.GRAYSCALE); } break; case 'lab': if (doc.mode != DocumentMode.LAB) { doc.changeMode(ChangeMode.LAB); } break; default: alert('Unsupported color mode. Use RGB, CMYK, or Grayscale.'); return; } } // ******************************************************************************************************** // ** ** // ** check for correct bit depth and if required adjust ** // ** ** // ******************************************************************************************************** function checkBitDepth() { var procesBitmode = svgOpenOptions.bitMode; var doc = app.activeDocument; if (procesBitmode == 8) { if (doc.bitsPerChannel == BitsPerChannelType.SIXTEEN) { // Convert to 8-bit per channel doc.bitsPerChannel = BitsPerChannelType.EIGHT; } } if (procesBitmode == 16) { if (doc.bitsPerChannel == BitsPerChannelType.EIGHT) { // Convert to 16-bit per channel doc.bitsPerChannel = BitsPerChannelType.SIXTEEN; } } } // ******************************************************************************************************** // ** ** // ** set button state for all buttons ** // ** ** // ******************************************************************************************************** function setButtons() { button_cancel.enabled = false; button_convert.enabled = false; button_about.enabled = false; button_fileStackAdd.enabled = false; button_fileStackRemove.enabled = false; button_fileStackClear.enabled = false; myTrimCropSettings.enabled = false; myDPISettings.enabled = false; myColorSettings.enabled = false; myBitsSettings.enabled = false; myAntiAliasedSettings.enabled = false; button_exportFolder.enabled = false; } // ******************************************************************************************************** // ** ** // ** restore button state for all buttons ** // ** ** // ******************************************************************************************************** function restoreButtons() { button_cancel.enabled = true; button_convert.enabled = true; button_about.enabled = true; button_fileStackAdd.enabled = true; button_fileStackRemove.enabled = true; button_fileStackClear.enabled = true; myTrimCropSettings.enabled = true; myDPISettings.enabled = true; myColorSettings.enabled = true; myBitsSettings.enabled = true; myAntiAliasedSettings.enabled = true; button_exportFolder.enabled = true; } // ******************************************************************************************************** // ** ** // ** execute main script ** // ** ** // ******************************************************************************************************** function ConvertStackListtoPSD() { // temporary disable buttons setButtons(); // initial check for items and path try { // are there files in the stack? if ( ListBox1.items.length == 0 ) { alert ('No files selected.\n\nChoose one or more files to convert before pressing the convert button.'); restoreButtons(); return; } // is export path set? if ( FileBasePath == '' ) { alert ('Invalid output folder.\n\nPlease specify an export location (output folder) for new documents.'); restoreButtons(); return; } // check if path exists var CheckPath = Folder(FileBasePath); if ( CheckPath.exists == 0) { alert ('Invalid output folder.\n\nPlease use the Choose Button to select your output folder.'); restoreButtons(); return; } } catch(err) { alert(err.message); ErrorList.push ( err ); } // set initial no choose options try { noChoiceOptions(); } catch(err) { alert(err.message); ErrorList.push ( err ); } // set values conform export options try { ChoiceOptions(); } catch(err) { alert(err.message); ErrorList.push ( err ); } // process all items in stack list try { // set progressbar counter var IncrementalValue = (100 / ListBox1.items.length) / 2; // 2 because update progress on both open and save actions ProgressProgressBar.value = 0; // set progressbar to 0; // process all files in stack for (var m = 0; m < ListBox1.items.length; m++) { // open ai or pdf document importFromAI(m, IncrementalValue); // check for correct color model and if required adjust checkColorModel(); // check for correct bit depth and if required adjust checkBitDepth(); // save document as psd saveAsPSD(m, IncrementalValue); } } catch(err) { alert(err.message); ErrorList.push ( err ); } // restore buttons restoreButtons(); // show message that export is finished ProgressProgressBar.value = 100; ProgressLabel.text = 'Converted : ' + ListBox1.items.length + ' files into native Photoshop PSD file format.'; if (ErrorList.length === 0) { alert ("Script finished.\n\nConverted : " + ListBox1.items.length + " files into native Photoshop PSD file format."); button_cancel.text = "Close"; } else { var ErrorString = "\n\n"; for (var i = 0; i < ErrorList.length; i++) { ErrorString += ErrorList[i] + "\n"; // Get the current item } alert ("One or more errors occured:" + ErrorString); } scriptdialog.update(); } // ******************************************************************************************************************************* // ******************************************************************************************************************************* // ******************************************************************************************************************************* // ******************************************************************************************************************************* // ******************************************************************************************************************************* // ******************************************************************************************************************************* // ******************************************************************************************************************************* // ******************************************************************************************************************************* // ******************************************************************************************************************************* // ******************************************************************************************************************************* // ******************************************************************************************************************************* // ******************************************************************************************************************************* // ******************************************************************************************************** // ** ** // ** building and showing main dialog ** // ** ** // ******************************************************************************************************** // Function to open the second dialog function showCopyrightDialog() { // Create second dialog window var copyrightDialog = new Window("dialog", "Copyright Information"); // Add static text to display copyright info var textGroup = copyrightDialog.add("group"); textGroup.orientation = "column"; var line1 = textGroup.add("statictext", undefined, "RasterizeVectorFiles.jsx"); line1.alignment = "left"; line1.preferredSize.height = 14; var line2 = textGroup.add("statictext", undefined, ""); line2.alignment = "left"; line2.preferredSize.height = 14; var line3 = textGroup.add("statictext", undefined, "Copyright © 2024 No-Nonsens inc. All rights reserved."); line3.alignment = "left"; line3.preferredSize.height = 14; var line4 = textGroup.add("statictext", undefined, "written by Michel Simons / No-Nonsens inc."); line4.alignment = "left"; line4.preferredSize.height = 14; var line5 = textGroup.add("statictext", undefined, "https://www.no-nonsens.nl"); line5.alignment = "left"; line5.preferredSize.height = 14; var line6 = textGroup.add("statictext", undefined, "released under a Creative Commons Attribution-NoDerivatives 4.0 International License."); line6.alignment = "left"; line6.preferredSize.height = 14; var closeButton = copyrightDialog.add("button", undefined, "Close", {name: "ok"}); // Show the copyright dialog copyrightDialog.show(); } // ******************************************************************************************************** // ** ** // ** building and showing main dialog ** // ** ** // ******************************************************************************************************** // Export dialog var scriptdialog = new Window('dialog'); scriptdialog.text = 'Convert multiple vector files into the Photoshop PSD or PSB file format - v' + ScriptVersion; scriptdialog.preferredSize.width = 550; scriptdialog.preferredSize.height = 400; scriptdialog.orientation = "column"; scriptdialog.alignChildren = ["center","top"]; scriptdialog.spacing = 10; scriptdialog.margins = 16; // PANEL1 - usage instructions // ========= var panel1 = scriptdialog.add("panel", undefined, undefined, {name: "panel1"}); panel1.text = "Rasterize AI, PDF, SVG and EPS files into Photoshop files:"; panel1.preferredSize.width = 550; panel1.preferredSize.height = 60; panel1.orientation = "column"; panel1.alignChildren = ["left","top"]; panel1.spacing = 22; panel1.margins = 10; // GROUP 1 // ========= var group1 = panel1.add('group', undefined, {name: "group1"}); group1.orientation = 'row'; group1.alignment = ["left","top"]; group1.size = [556,70]; // Labels var statictext1 = group1.add("statictext", undefined, undefined, {name: "statictext1", multiline: true}); statictext1.text = '\nThis script converts PDF, AI (PDF compatible), SVG and EPS vector files into the native Photoshop PSD file format. Note that thin strokes may disappear when rasterizing with less than 300 pixels/inch resolution. Files exceeding 30000 pixels (width or height) or the 2Gb file size limitation will be saved in the Photoshop PSB Large Document Format.'; statictext1.preferredSize.width = 550; // PANEL 2 with file stack // ========= panel2 = scriptdialog.add("panel", undefined, undefined, {name: "panel2"}); panel2.text = "Vector files processing list:"; // GROUP panel2.orientation = 'row'; panel2.alignChildren = "top"; // GROUP 2a // ========= var group2a = panel2.add('group') group2a.orientation = 'column'; var ListBox1 = group2a.add ("listbox",undefined,[],{multiselect: true}); ListBox1.preferredSize = [416,120]; // GROUP 2b // ========= var group2b = panel2.add ("group"); group2b.orientation = 'column'; group2b.size = [120,120]; // var button_fileStackAdd = group2b.add("button", undefined, "Add ... " ); button_fileStackAdd.preferredSize.width = 110; // Remove Files Button var button_fileStackRemove = group2b.add("button", undefined, "Remove ..." ); button_fileStackRemove.preferredSize.width = 110; // Clear Files Button var button_fileStackClear = group2b.add("button", undefined, "Clear ..." ); button_fileStackClear.preferredSize.width = 110; // PANEL 3 with Import Options // ========= var panel3 = scriptdialog.add("panel", undefined, undefined, {name: "panel3"}); panel3.text = "Vector rasterize options:"; // GROUP 3 // ========= var group3 = panel3.add('group', undefined, '') group3.alignChildren = "left"; group3.size = [550,35]; group3.orientation = 'row'; var myTrimCropSettings = group3.add ("dropdownlist", undefined, ["Bounding Box", "Media Box", "Crop Box", "Bleed Box", "Trim Box", "Art Box"]); myTrimCropSettings.preferredSize.width = 100; var myDPISettings = group3.add ("dropdownlist", undefined, ["72 pixels/inch", "100 pixels/inch", "150 pixels/inch", "200 pixels/inch", "300 pixels/inch", "600 pixels/inch", "1200 pixels/inch"]); myDPISettings.preferredSize.width = 120; var myColorSettings = group3.add ("dropdownlist", undefined, ["Grayscale","RGB Color", "CMYK Color", "Lab Color"]); myColorSettings.preferredSize.width = 100; var myBitsSettings = group3.add ("dropdownlist", undefined, ["8 bits","16 bits"]); myBitsSettings.preferredSize.width = 80; var myAntiAliasedSettings = group3.add ("checkbox", undefined, "Anti-aliased"); // PANEL 4 with Export Location // ========= var panel4 = scriptdialog.add("panel", undefined, undefined, {name: "panel4"}); panel4.text = "Converted files output folder:"; // GROUP 4 // ========= var group4 = panel4.add( 'group', undefined, '') group4.orientation = 'row'; group4.alignment = ["left","top"]; group4.size = [550,30]; // Edit var ExportEdit = group4.add('edittext', undefined, "",{readonly:true}); ExportEdit.size = [ 430,20 ]; // Choose Button var button_exportFolder = group4.add('button', undefined, 'Choose ...' ); button_exportFolder.preferredSize.width = 110; // PANEL 5 with Progressbar // ========= var panel5 = scriptdialog.add("panel", undefined, undefined, {name: "panel5"}); panel5.text = "Progress / Status:"; // GROUP 5 // ========= var group5 = panel5.add('group', undefined, '') group5.orientation = 'column'; group5.alignment = ["left","top"] group5.size = [550,50]; // progressbar var ProgressProgressBar = group5.add( 'progressbar', undefined, 0, 100 ); ProgressProgressBar.size = [530,10]; // label var ProgressLabel = group5.add('statictext', undefined, ListBox1.items.length + ' files are waiting for conversion.' ); ProgressLabel.size = [ 530,20 ]; // Buttons don't have a PANEL // GROUP 6 // ========= group6 = scriptdialog.add('group', undefined, ''); group6.orientation = 'row'; button_cancel = group6.add('button', undefined, undefined, {name:'cancelbutton'}); button_cancel.text = 'Cancel'; button_convert = group6.add('button', undefined, undefined, {name:'convertbutton'}); button_convert.text = 'Convert'; button_convert.enabled = false; button_about = group6.add('button', undefined, undefined, {name:'aboutbutton'}); button_about.text = 'About'; // rasterize options myTrimCropSettings.selection = 4; // start with 0 myDPISettings.selection = 4; // start with 0 myColorSettings.selection = 2; // start with 0 myBitsSettings.selection = 0; // start with 0 myAntiAliasedSettings.value = true; //helper button functions button_fileStackAdd.onClick = function() { try { AddFilesToDialog(); } catch(err) { alert (err); ErrorList.push ( err );}} button_fileStackRemove.onClick = function() { try { removeFilesFromDialog(); } catch(err) { alert (err); ErrorList.push ( err );}} button_fileStackClear.onClick = function() { try { clearFilesfromDialog(); } catch(err) { alert (err); ErrorList.push ( err );}} //main button functions button_cancel.onClick = function() { scriptdialog.close(); }; button_about.onClick = function() { showCopyrightDialog(); /*alert(system_message_1);*/ }; button_convert.onClick = function() { ConvertStackListtoPSD(); }; button_exportFolder.onClick = function() { var InitialFolder = ""; if (ExportEdit.text.length == 0) { InitialFolder = Folder(ExportEdit.text); if( !InitialFolder.exists ) { InitialFolder = Folder("~/Desktop"); } } var ResultSaveLocation = Folder.selectDialog("Select destination folder",InitialFolder); FileBasePath = ResultSaveLocation.fsName.toString(); ExportEdit.text = FileBasePath; } scriptdialog.show();