Images To PDF

Script for Adobe Photoshop

The script creates a single PDF with page for each image currently open in Photoshop, or each image in a selected folder.

  • Open images or a folder of images
  • Include subfolders
  • Choose PDF preset
  • Adapt open source to customize or create other scripts
Download
Images To PDF
Help me keep making new scripts by supporting my work. Click the PayPal button to contribute any amount you choose. Thank you. William Campbell

How-to Video

NOTE: after video production, the option Open images was added. See instructions below for details.

How to use the script

The interface has two sections: Input and Output. Set desired options then click the OK button to begin.

Section 1: Input

Open images — images currently open in Photoshop are added to the output PDF.

Folder — click the Folder button below to select a folder of images that are added to the output PDF.

Include subfolders — if enabled, images in all subfolders are included.

Section 2: Output

PDF preset — the preset used to output the PDF. If a PDF preset is not selected in the list, the script uses values manually set in the script code, which is well-commented and may be adjusted to suit your needs. See the source code comments for more details.

File — the PDF file to create. Click the File button to set the file location and name.

Source code

(download button below)

Near the top of the script is the variable defaults. This is a JavaScript object that holds multiple properties which are loaded into the interface controls when the script is launched. To set the default input folder, subfolders option, PDF preset, and output file path and name, edit these values as desired. For input folder and output file paths, use only forward slashes for path separators, even for Windows where normally backslashes are used. Do not use backslashes as doing so will not work.

/*

Images To PDF
Copyright 2024 William Campbell
All Rights Reserved
https://www.marspremedia.com/contact

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

*/

(function () {

    var defaults = {
        folderInput: "",
        subfolders: false,
        pdfPreset: "[High Quality Print]",
        fileOutput: ""
    };

    var title = "Images To PDF";

    if (!/photoshop/i.test(app.name)) {
        alert("Script for Photoshop", title, false);
        return;
    }

    app.displayDialogs = DialogModes.ERROR;

    // Script variables
    var doneMessage;
    var error;
    var filePdf;
    var folderInput;
    var pdfPresetNames;
    var working;

    // Reusable UI variables
    var g; // group
    var p; // panel
    var w; // window

    // Permanent UI variables
    var btnCancel;
    var btnFileOutput;
    var btnFolderInput;
    var btnOk;
    var cbSubfolders;
    var grpFolder;
    var listPdfPreset;
    var rbFolder;
    var rbOpenImages;
    var txtFileOutput;
    var txtFolderInput;

    // SETUP

    // Get PDF preset names.
    pdfPresetNames = loadPdfPresets();

    // CREATE WORKING WINDOW

    working = new Window("palette");
    working.preferredSize = [300, 80];
    working.add("statictext");
    working.t = working.add("statictext");
    working.add("statictext");
    working.display = function (message) {
        this.t.text = message || "Working... Please wait...";
        this.show();
        app.refresh();
    };

    // CREATE USER INTERFACE

    w = new Window("dialog", title);
    w.alignChildren = "fill";

    // Panel 'Input'
    p = w.add("panel", undefined, "Input");
    p.alignChildren = "left";
    p.margins = [24, 18, 18, 18];
    g = p.add("group");
    rbOpenImages = g.add("radiobutton", undefined, "Open images");
    rbFolder = g.add("radiobutton", undefined, "Folder");
    cbSubfolders = g.add("checkbox", undefined, "Include subfolders");
    grpFolder = p.add("group");
    btnFolderInput = grpFolder.add("button", undefined, "Folder...");
    txtFolderInput = grpFolder.add("statictext", undefined, undefined, {
        truncate: "middle"
    });
    txtFolderInput.preferredSize.width = 250;

    // Panel 'Output'
    p = w.add("panel", undefined, "Output");
    p.margins = [24, 18, 18, 18];
    p.alignChildren = "left";
    g = p.add("group");
    g.alignment = "left";
    g.add("statictext", undefined, "PDF preset:");
    listPdfPreset = g.add("dropdownlist", undefined, pdfPresetNames);
    g = p.add("group");
    btnFileOutput = g.add("button", undefined, "File...");
    txtFileOutput = g.add("statictext", undefined, undefined, {
        truncate: "middle"
    });
    txtFileOutput.preferredSize.width = 250;

    // Action buttons
    g = w.add("group");
    g.alignment = "center";
    btnOk = g.add("button", undefined, "OK");
    btnCancel = g.add("button", undefined, "Cancel");

    // Panel Copyright
    p = w.add("panel");
    p.add("statictext", undefined, "Copyright 2024 William Campbell");

    // SET UI VALUES

    txtFolderInput.text = defaults.folderInput;
    cbSubfolders.value = defaults.subfolders;
    listPdfPreset.selection = defaults.pdfPreset;
    txtFileOutput.text = defaults.fileOutput;

    configureUi();

    // UI EVENT HANDLERS

    rbOpenImages.onClick = configureUi;
    rbFolder.onClick = configureUi;

    btnFolderInput.onClick = function () {
        var f = Folder.selectDialog("Select input folder", txtFolderInput.text);
        if (f) {
            txtFolderInput.text = Folder.decode(f.fullName);
            filePdf = new File(f.path + "/" + f.name + ".pdf");
            txtFileOutput.text = File.decode(filePdf.fullName);
        }
    };

    btnFileOutput.onClick = function () {
        var f;
        f = File.saveDialog();
        if (f) {
            filePdf = f;
            if (!/\.pdf$/i.test(filePdf.fullName)) {
                filePdf = new File(filePdf.fullName + ".pdf");
            }
            txtFileOutput.text = File.decode(filePdf.fullName);
        }
    };

    btnOk.onClick = function () {
        if (rbFolder.value) {
            folderInput = new Folder(txtFolderInput.text);
            if (!(folderInput && folderInput.exists)) {
                txtFolderInput.text = "";
                alert("Select input folder", " ", false);
                return;
            }
        }
        if (!listPdfPreset.selection) {
            alert("Select a PDF preset", " ", false);
            return;
        }
        if (!filePdf) {
            alert("Select output file", " ", false);
            return;
        }
        w.close(1);
    };

    btnCancel.onClick = function () {
        w.close(0);
    };

    // SHOW THE WINDOW

    if (w.show() == 1) {
        try {
            process();
            doneMessage = "Done";
        } catch (e) {
            if (/User cancel/.test(e.message)) {
                doneMessage = "Canceled";
            } else {
                error = error || e;
                doneMessage = "An error has occurred.\nLine " + error.line + ": " + error.message;
            }
        }
        app.bringToFront();
        working.close();
        doneMessage && alert(doneMessage, title, error);
    }

    //====================================================================
    //               END PROGRAM EXECUTION, BEGIN FUNCTIONS
    //====================================================================

    function configureUi() {
        if (!(rbOpenImages.value || rbFolder.value)) {
            rbFolder.value = true;
        }
        if (!app.documents.length) {
            rbOpenImages.value = false;
            rbOpenImages.enabled = false;
            rbFolder.value = true;
        }
        cbSubfolders.enabled = rbFolder.value;
        grpFolder.enabled = rbFolder.value;
    }

    function getFiles(folder, subfolders, extensions) {
        // folder = folder object, not folder name.
        // subfolders = true to include subfolders.
        // extensions = string, extensions to include.
        // Combine multiple extensions with RegExp OR i.e. jpg|psd|tif
        // extensions case-insensitive.
        // extensions undefined = any.
        // Ignores hidden files and folders.
        var f;
        var files;
        var i;
        var pattern;
        var results = [];
        if (extensions) {
            pattern = new RegExp("\." + extensions + "$", "i");
        } else {
            // Any extension.
            pattern = new RegExp(
                "\.8PBS|AFX|AI|ARW|BLZ|BMP|CAL|CALS|CIN|CR2|CRW|CT|DCM|DCR|DCS|DCX|DDS|" +
                "DIB|DIC|DNG|DPX|EPS|EPSF|EXR|FFF|FIF|GIF|HDP|HDR|HEIC|HEIF|ICB|ICN|ICO|" +
                "ICON|IIQ|IMG|J2C|J2K|JIF|JIFF|JP2|JPC|JPE|JPEG|JPF|JPG|JPS|JPX|JXR|KDK|" +
                "KMZ|KODAK|MOS|MRW|NCR|NEF|ORF|PAT|PBM|PCT|PCX|PDD|PDF|PDP|PEF|PGM|PICT|" +
                "PMG|PNG|PPM|PS|PSB|PSD|PSDC|PSID|PVR|PXR|RAF|RAW|RLE|RSR|SCT|SRF|TGA|TIF|" +
                "TIFF|TRIF|U3D|VDA|VST|WBMP|WDP|WEBP|WMP|X3F$", "i");
        }
        files = folder.getFiles();
        for (i = 0; i < files.length; i++) {
            f = files[i];
            if (!f.hidden) {
                if (f instanceof Folder && subfolders) {
                    // Recursive (function calls itself).
                    results = results.concat(getFiles(f, subfolders, extensions));
                } else if (f instanceof File && pattern.test(f.name)) {
                    results.push(f);
                }
            }
        }
        return results;
    }

    function loadPdfPresets() {
        var files;
        var i;
        var names;
        files = new Folder(Folder.userData + "/Adobe/Adobe PDF/Settings").getFiles("*.joboptions");
        names = [
            "[High Quality Print]",
            "[PDF/X-1a:2001]",
            "[PDF/X-3:2002]",
            "[PDF/X-4:2008]",
            "[Press Quality]",
            "[Smallest File Size]"
        ];
        for (i = 0; i < files.length; i++) {
            names.push(File.decode(files[i].name).replace(/\.joboptions$/i, ""));
        }
        return names;
    }

    function pdfSaveOptions() {
        var o = new PDFSaveOptions();
        if (listPdfPreset.selection) {
            // Use PDF preset.
            // Have to strip brackets [ ] from name if present.
            o.presetFile = listPdfPreset.selection.text.replace(/[\[\]]/g, "");
        } else {
            // Set properties using values enabled below.

            // o.PDFCompatibility = PDFCompatibility.PDF13;
            // o.PDFCompatibility = PDFCompatibility.PDF14;
            // o.PDFCompatibility = PDFCompatibility.PDF15;
            // o.PDFCompatibility = PDFCompatibility.PDF16;
            // o.PDFCompatibility = PDFCompatibility.PDF17;
            o.PDFCompatibility = PDFCompatibility.PDF17;

            o.PDFStandard = PDFStandard.NONE;
            // o.PDFStandard = PDFStandard.PDFX1A2001;
            // o.PDFStandard = PDFStandard.PDFX1A2003;
            // o.PDFStandard = PDFStandard.PDFX32002;
            // o.PDFStandard = PDFStandard.PDFX32003;
            // o.PDFStandard = PDFStandard.PDFX42008;

            o.colorConversion = true; // convert to destinationProfile
            o.description = ""; // description of the save options in use
            o.destinationProfile = "sRGB IEC61966-2.1";

            // o.downSample = PDFResample.NONE;
            // o.downSample = PDFResample.PDFAVERAGE;
            // o.downSample = PDFResample.PDFSUBSAMPLE;
            o.downSample = PDFResample.PDFBICUBIC;

            o.downSampleSize = 150; // pixels per inch desired
            o.downSampleSizeLimit = 150; // only images pixels per inch greater than this value
            o.embedColorProfile = false;
            o.embedThumbnail = true;

            // o.encoding = PDFEncoding.NONE;
            // o.encoding = PDFEncoding.PDFZIP;
            o.encoding = PDFEncoding.JPEG;
            // o.encoding = PDFEncoding.PDFZIP4BIT;
            // o.encoding = PDFEncoding.JPEGHIGH;
            // o.encoding = PDFEncoding.JPEGMEDHIGH;
            // o.encoding = PDFEncoding.JPEGMED;
            // o.encoding = PDFEncoding.JPEGMEDLOW;
            // o.encoding = PDFEncoding.JPEGLOW;
            // o.encoding = PDFEncoding.JPEG2000HIGH;
            // o.encoding = PDFEncoding.JPEG2000MEDHIGH;
            // o.encoding = PDFEncoding.JPEG2000MED;
            // o.encoding = PDFEncoding.JPEG2000MEDLOW;
            // o.encoding = PDFEncoding.JPEG2000LOW;
            // o.encoding = PDFEncoding.JPEG2000LOSSLESS;

            o.jpegQuality = 8; // range 0 to 12
            o.optimizeForWeb = true;
            // o.tileSize = null; // integer value JPEG2000 compression only

        }
        // These properties set either way.
        o.alphaChannels = false;
        o.annotations = false;
        o.convertToEightBit = true;
        o.layers = false;
        o.preserveEditing = false; // true retains Photoshop data
        o.spotColors = false;
        o.view = false; // true opens PDF in Acrobat after saving it
        return o;
    }

    function presentationOptions() {
        var o = new PresentationOptions();
        o.PDFFileOptions = pdfSaveOptions();
        o.presentation = false;
        // Remainder have no effect when presentation is false
        if (o.presentation) {
            o.autoAdvance = true;
            o.includeFilename = false;
            o.interval = 5;
            o.loop = false;

            // o.magnification = MagnificationType.ACTUALSIZE;
            o.magnification = MagnificationType.FITPAGE;

            // o.transistion = TransitionType.BLINDSHORIZONTAL;
            // o.transistion = TransitionType.BLINDSVERTICAL;
            // o.transistion = TransitionType.DISSOLVE;
            // o.transistion = TransitionType.BOXIN;
            // o.transistion = TransitionType.BOXOUT;
            // o.transistion = TransitionType.GLITTERDOWN;
            // o.transistion = TransitionType.GLITTERRIGHT;
            // o.transistion = TransitionType.GLITTERRIGHTDOWN;
            o.transistion = TransitionType.NONE;
            // o.transistion = TransitionType.RANDOM;
            // o.transistion = TransitionType.SPLITHORIZONTALIN;
            // o.transistion = TransitionType.SPLITHORIZONTALOUT;
            // o.transistion = TransitionType.SPLITVERTICALIN;
            // o.transistion = TransitionType.SPLITVERTICALOUT;
            // o.transistion = TransitionType.WIPEDOWN;
            // o.transistion = TransitionType.WIPELEFT;
            // o.transistion = TransitionType.WIPERIGHT;
            // o.transistion = TransitionType.WIPEUP;
        }
        return o;
    }

    function process() {
        var files;
        app.displayDialogs = DialogModes.NO;
        working.display();
        try {
            if (rbOpenImages.value) {
                files = [];
                for (var i = 0; i < app.documents.length; i++) {
                    files.push(app.documents[i].fullName);
                }
            }
            if (rbFolder.value) {
                // Get files in folder.
                files = getFiles(folderInput, cbSubfolders.value);
                if (!files.length) {
                    doneMessage = "No files found in selected folder";
                    return;
                }
            }
            // Make presentation (multi-page PDF of the images)
            app.makePDFPresentation(files, filePdf, presentationOptions());
        } finally {
            app.displayDialogs = DialogModes.ERROR;
        }
    }

})();
Help me keep making new scripts by supporting my work. Click the PayPal button to contribute any amount you choose. Thank you. William Campbell
Download
Images To PDF

For help installing scripts, see How to Install and Use Scripts in Adobe Creative Cloud Applications.

IMPORTANT: scripts are developed for the latest Adobe Creative Cloud applications. Many scripts work in CC 2018 and later, even some as far back as CS6, but may not perform as expected, or run at all, when used in versions prior to 2018. Photoshop features Select Subject and Preserve Details 2.0 definitely fail prior to CC 2018 (version 19) as the features do not exist in earlier versions. For best results use the latest versions of Adobe Creative Cloud applications.

IMPORTANT: by downloading any of the scripts on this page you agree that the software is provided without any warranty, express or implied. USE AT YOUR OWN RISK. Always make backups of important data.

IMPORTANT: fees paid for software products are the purchase of a non-exclusive license to use the software product and do not grant the purchaser any degree of ownership of the software code. Author of the intellectual property and copyright holder William Campbell retains 100% ownership of all code used in all software products regardless of the inspiration for the software product design or functionality.