Skip to main content
hameedfarah
Known Participant
March 27, 2022
Answered

Place many PNGs on many different backgrounds

  • March 27, 2022
  • 7 replies
  • 2442 views

I am looking for a way to place many transparent PNGs (Say 500 PNGs) on top of many different backgrounds (Over 20 backgrounds).

 

The end result would be 500 JPGs for each PNG file but each with a randomly picked background.

 

Any help please?

This topic has been closed for replies.
Correct answer Stephen Marsh

Here is the final 1.4 script, there is no longer any need to use an action or batch/image processor/image processor pro as this script is now self-contained. You will be prompted to select the JPG, PNG and Save folders and the script will then create the final combined JPG files with random backgrounds.

 

 

/*

Place Random Background Image.jsx
Version 1.4, Stephen Marsh, 3rd April 2022 
https://community.adobe.com/t5/photoshop-ecosystem-discussions/place-many-pngs-on-many-different-backgrounds/td-p/12839669

Notes:
  * Random background images in JPEG format, 1000 x 1000 px
  * Random background image filename must be consistent and have variable digits, 
    i.e.: bk (5).jpg, bk (20).jpg or Post_4.jpg, Post_11.jpg etc
  * Variable foreground images in transparent PNG format, various sizes fitted to 800 x 800px
  * Foreground to be centered on background

*/

#target photoshop

    (function () {

        try {

            // JPEG folder selection
            var jpgFolder = Folder.selectDialog("Select the random JPG background image folder:");
            if (jpgFolder === null) {
                alert('Script cancelled!');
                return;
            }

            // PNG folder selection
            var pngFolder = Folder.selectDialog("Select the transparent PNG foreground image folder:");
            if (pngFolder === null) {
                alert('Script cancelled!');
                return;
            }

            // Validate input folders
            var validateInputDir = (jpgFolder.fsName === pngFolder.fsName);
            if (validateInputDir === true) {
                alert("Script cancelled as both the input folders are the same!");
                return;
            }

            // Limit the file input
            var jpgList = jpgFolder.getFiles(/\.(jpg|jpeg)$/i);
            var pngList = pngFolder.getFiles(/\.(png)$/i);

            // Validate that the JPEG list isn't empty 
            var validateJPEGEmptyList = (jpgList.length > 0);
            if (validateJPEGEmptyList === false) {
                alert("Script cancelled as the JPEG input folder is empty!");
                return;
            }

            // Validate that the PNG list isn't empty 
            var validatePNGEmptyList = (jpgList.length > 0);
            if (validatePNGEmptyList === false) {
                alert("Script cancelled as the PNG input folder is empty!");
                return;
            }

            // Output folder selection
            var saveFolder = Folder.selectDialog("Please select the folder to save to...");
            if (saveFolder === null) {
                alert('Script cancelled!');
                return;
            }

            // Save and set the dialog display settings
            var savedDisplayDialogs = app.displayDialogs;
            app.displayDialogs = DialogModes.NO;

            // Perform the stacking and saving
            for (var i = 0; i < pngList.length; i++) {
                var doc = open(pngList[i]);
                var docName = activeDocument.name.replace(/\.[^\.]+$/, '');
                activeDocument.resizeCanvas(UnitValue(1000, "px"), UnitValue(1000, "px"), AnchorPosition.MIDDLECENTER);
                // Count the JPEG files
                var bgCount = jpgList.length;
                // Random generator based on the JPEG files count
                var bgNumber = Math.floor(Math.random() * bgCount) + 1;
                // Random background file name using random variable
                var randomBaseName = jpgList[0].displayName.replace(/\d+/, bgNumber);
                var bgFileName = jpgFolder + "/" + randomBaseName;

                placeFile(bgFileName, 100);
                centreActiveLayerToCanvas();
                moveLayerRelativeStack("previous");

                // JPEG save options
                var jpgOptions = new JPEGSaveOptions();
                jpgOptions.formatOptions = FormatOptions.STANDARDBASELINE;
                jpgOptions.embedColorProfile = true;
                jpgOptions.matte = MatteType.NONE;
                jpgOptions.quality = 10;
                doc.saveAs(new File(saveFolder + '/' + docName + '.jpg'), jpgOptions);
                doc.close(SaveOptions.DONOTSAVECHANGES);
            }

            // End of script
            app.displayDialogs = savedDisplayDialogs;
            app.beep();
            alert('Script completed!' + '\r' + pngList.length + ' JPEG files (quality level 10) saved to:' + '\r' + saveFolder.fsName);

        } catch (err) {
            while (documents.length > 0) {
                activeDocument.close(SaveOptions.DONOTSAVECHANGES);
            }
            alert("An unexpected error has occurred!");
        }


        /***** FUNCTIONS *****/

        function centreActiveLayerToCanvas() {
            var doc = app.activeDocument;
            var docLay = app.activeDocument.activeLayer;
            docLay.translate(doc.width / 2 - (docLay.bounds[0] + docLay.bounds[2]) / 2,
                doc.height / 2 - (docLay.bounds[1] + docLay.bounds[3]) / 2);
        }

        function moveLayerRelativeStack(relPos) {
            // "previous" or "next" or "front" or "back"
            var c2t = function (s) {
                return app.charIDToTypeID(s);
            };
            var s2t = function (s) {
                return app.stringIDToTypeID(s);
            };
            var descriptor = new ActionDescriptor();
            var reference = new ActionReference();
            var reference2 = new ActionReference();
            reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
            descriptor.putReference(c2t("null"), reference);
            reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t(relPos));
            descriptor.putReference(s2t("to"), reference2);
            executeAction(s2t("move"), descriptor, DialogModes.NO);
        }

        function placeFile(file, scale) {
            try {
                var idPlc = charIDToTypeID("Plc ");
                var desc2 = new ActionDescriptor();
                var idnull = charIDToTypeID("null");
                desc2.putPath(idnull, new File(file));
                var idFTcs = charIDToTypeID("FTcs");
                var idQCSt = charIDToTypeID("QCSt");
                var idQcsa = charIDToTypeID("Qcsa");
                desc2.putEnumerated(idFTcs, idQCSt, idQcsa);
                var idOfst = charIDToTypeID("Ofst");
                var desc3 = new ActionDescriptor();
                var idHrzn = charIDToTypeID("Hrzn");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idHrzn, idPxl, 0.000000);
                var idVrtc = charIDToTypeID("Vrtc");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idVrtc, idPxl, 0.000000);
                var idOfst = charIDToTypeID("Ofst");
                desc2.putObject(idOfst, idOfst, desc3);
                var idWdth = charIDToTypeID("Wdth");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idWdth, idPrc, scale);
                var idHght = charIDToTypeID("Hght");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idHght, idPrc, scale);
                var idAntA = charIDToTypeID("AntA");
                desc2.putBoolean(idAntA, true);
                executeAction(idPlc, desc2, DialogModes.NO);
            } catch (e) {}
        }

    }());

 

 

 

7 replies

Arafin Sardar
Known Participant
April 2, 2022

You can do it very easily by using widely used and multi-featured software called Adobe Photoshop. With the pen tool of Photoshop, you can make multiple paths in which portion you want to change the background.

Professional Product Photo Editor
Kukurykus
Legend
April 2, 2022

Where do you see an author asks how to cut out subject from image?

Stephen Marsh
Community Expert
Community Expert
March 30, 2022

@hameedfarah  So how did you go with the two final scripts posted by @c.pfaffenbichler and myself?

hameedfarah
Known Participant
March 30, 2022

I am so sorry for the lack of feedback. I had a faimly emergency.

I should be able to use the scripts tomorrow

 

Thank you so much for your kind work. You guys are truly amazing!

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
March 28, 2022

Here is the final 1.4 script, there is no longer any need to use an action or batch/image processor/image processor pro as this script is now self-contained. You will be prompted to select the JPG, PNG and Save folders and the script will then create the final combined JPG files with random backgrounds.

 

 

/*

Place Random Background Image.jsx
Version 1.4, Stephen Marsh, 3rd April 2022 
https://community.adobe.com/t5/photoshop-ecosystem-discussions/place-many-pngs-on-many-different-backgrounds/td-p/12839669

Notes:
  * Random background images in JPEG format, 1000 x 1000 px
  * Random background image filename must be consistent and have variable digits, 
    i.e.: bk (5).jpg, bk (20).jpg or Post_4.jpg, Post_11.jpg etc
  * Variable foreground images in transparent PNG format, various sizes fitted to 800 x 800px
  * Foreground to be centered on background

*/

#target photoshop

    (function () {

        try {

            // JPEG folder selection
            var jpgFolder = Folder.selectDialog("Select the random JPG background image folder:");
            if (jpgFolder === null) {
                alert('Script cancelled!');
                return;
            }

            // PNG folder selection
            var pngFolder = Folder.selectDialog("Select the transparent PNG foreground image folder:");
            if (pngFolder === null) {
                alert('Script cancelled!');
                return;
            }

            // Validate input folders
            var validateInputDir = (jpgFolder.fsName === pngFolder.fsName);
            if (validateInputDir === true) {
                alert("Script cancelled as both the input folders are the same!");
                return;
            }

            // Limit the file input
            var jpgList = jpgFolder.getFiles(/\.(jpg|jpeg)$/i);
            var pngList = pngFolder.getFiles(/\.(png)$/i);

            // Validate that the JPEG list isn't empty 
            var validateJPEGEmptyList = (jpgList.length > 0);
            if (validateJPEGEmptyList === false) {
                alert("Script cancelled as the JPEG input folder is empty!");
                return;
            }

            // Validate that the PNG list isn't empty 
            var validatePNGEmptyList = (jpgList.length > 0);
            if (validatePNGEmptyList === false) {
                alert("Script cancelled as the PNG input folder is empty!");
                return;
            }

            // Output folder selection
            var saveFolder = Folder.selectDialog("Please select the folder to save to...");
            if (saveFolder === null) {
                alert('Script cancelled!');
                return;
            }

            // Save and set the dialog display settings
            var savedDisplayDialogs = app.displayDialogs;
            app.displayDialogs = DialogModes.NO;

            // Perform the stacking and saving
            for (var i = 0; i < pngList.length; i++) {
                var doc = open(pngList[i]);
                var docName = activeDocument.name.replace(/\.[^\.]+$/, '');
                activeDocument.resizeCanvas(UnitValue(1000, "px"), UnitValue(1000, "px"), AnchorPosition.MIDDLECENTER);
                // Count the JPEG files
                var bgCount = jpgList.length;
                // Random generator based on the JPEG files count
                var bgNumber = Math.floor(Math.random() * bgCount) + 1;
                // Random background file name using random variable
                var randomBaseName = jpgList[0].displayName.replace(/\d+/, bgNumber);
                var bgFileName = jpgFolder + "/" + randomBaseName;

                placeFile(bgFileName, 100);
                centreActiveLayerToCanvas();
                moveLayerRelativeStack("previous");

                // JPEG save options
                var jpgOptions = new JPEGSaveOptions();
                jpgOptions.formatOptions = FormatOptions.STANDARDBASELINE;
                jpgOptions.embedColorProfile = true;
                jpgOptions.matte = MatteType.NONE;
                jpgOptions.quality = 10;
                doc.saveAs(new File(saveFolder + '/' + docName + '.jpg'), jpgOptions);
                doc.close(SaveOptions.DONOTSAVECHANGES);
            }

            // End of script
            app.displayDialogs = savedDisplayDialogs;
            app.beep();
            alert('Script completed!' + '\r' + pngList.length + ' JPEG files (quality level 10) saved to:' + '\r' + saveFolder.fsName);

        } catch (err) {
            while (documents.length > 0) {
                activeDocument.close(SaveOptions.DONOTSAVECHANGES);
            }
            alert("An unexpected error has occurred!");
        }


        /***** FUNCTIONS *****/

        function centreActiveLayerToCanvas() {
            var doc = app.activeDocument;
            var docLay = app.activeDocument.activeLayer;
            docLay.translate(doc.width / 2 - (docLay.bounds[0] + docLay.bounds[2]) / 2,
                doc.height / 2 - (docLay.bounds[1] + docLay.bounds[3]) / 2);
        }

        function moveLayerRelativeStack(relPos) {
            // "previous" or "next" or "front" or "back"
            var c2t = function (s) {
                return app.charIDToTypeID(s);
            };
            var s2t = function (s) {
                return app.stringIDToTypeID(s);
            };
            var descriptor = new ActionDescriptor();
            var reference = new ActionReference();
            var reference2 = new ActionReference();
            reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
            descriptor.putReference(c2t("null"), reference);
            reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t(relPos));
            descriptor.putReference(s2t("to"), reference2);
            executeAction(s2t("move"), descriptor, DialogModes.NO);
        }

        function placeFile(file, scale) {
            try {
                var idPlc = charIDToTypeID("Plc ");
                var desc2 = new ActionDescriptor();
                var idnull = charIDToTypeID("null");
                desc2.putPath(idnull, new File(file));
                var idFTcs = charIDToTypeID("FTcs");
                var idQCSt = charIDToTypeID("QCSt");
                var idQcsa = charIDToTypeID("Qcsa");
                desc2.putEnumerated(idFTcs, idQCSt, idQcsa);
                var idOfst = charIDToTypeID("Ofst");
                var desc3 = new ActionDescriptor();
                var idHrzn = charIDToTypeID("Hrzn");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idHrzn, idPxl, 0.000000);
                var idVrtc = charIDToTypeID("Vrtc");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idVrtc, idPxl, 0.000000);
                var idOfst = charIDToTypeID("Ofst");
                desc2.putObject(idOfst, idOfst, desc3);
                var idWdth = charIDToTypeID("Wdth");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idWdth, idPrc, scale);
                var idHght = charIDToTypeID("Hght");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idHght, idPrc, scale);
                var idAntA = charIDToTypeID("AntA");
                desc2.putBoolean(idAntA, true);
                executeAction(idPlc, desc2, DialogModes.NO);
            } catch (e) {}
        }

    }());

 

 

 

hameedfarah
Known Participant
April 1, 2022

Thank you so much @Stephen Marsh the script is great.

But two issues,

-Can the output be the same size as the background JOG rather than the input PNG?

-When the JPG files were named Post_01.jpg the script ignored them and just saved the PNGs as JPGs,  after renaming them to bk (1).jpg the script worked correctly

 

Stephen Marsh
Community Expert
Community Expert
April 1, 2022

 

@hameedfarah 

You previously stated that the backgrounds used a set naming convention of:

 

bk (##).jpg

 

This is what is hard-coded into the 1.2 version script. Are you now saying that the random background image filename is variable and not consistent?

 

c.pfaffenbichler
Community Expert
Community Expert
March 27, 2022

Another point: 

Do the pngs and the backgrounds (which file format are those by the way?) have the same proportions, pixel dimensions and resolution? 

If not: How exactly are the pngs and the backgrounds to be combined? Could you post examples? 

Stephen Marsh
Community Expert
Community Expert
March 27, 2022

I originally thought that this task was beyond my abilities, however, with some time to think about it I have a solution.

 

Here is the background folder, in this example, it has 6 background images, which could be 20+. It is important that the various filenames are consistent and based on digits/numbers:

 

 

Here are the PNG files, in this example, there are 12 files, however, this could be 500+:

 

 

And here is the combined result:

 

 

Here is a second run, with only 6 random images and 12 input files, there is obviously a lot of repetition. I don't know if there are "better" random number generators?

 

 

I will make a separate post with the code and screenshots of how to run...

Stephen Marsh
Community Expert
Community Expert
March 27, 2022

The JS code (original code edited):

 

/*
Place Random Background Image.jsx
Version 1.1, Stephen Marsh, 28th March 2022 
https://community.adobe.com/t5/photoshop-ecosystem-discussions/place-many-pngs-on-many-different-backgrounds/td-p/12839669
*/

//#target photoshop

	(function () {

		// Set the random background folder
		var bgFolder = Folder("~/Desktop/random-bg/");
		// Get and limit the returned objects to JPEG files
		var bgFiles = bgFolder.getFiles(/\.jpg$/i);
		// Count the JPEG files
		var bgCount = bgFiles.length;
		// Only used for debug console instead of alert
    	$.writeln(bgCount);

		var fileNumber = Math.floor(Math.random() * bgCount) + 1;
		var fileName = "~/Desktop/random-bg/bk (" + fileNumber + ").jpg"

		placeFile(fileName, 100);


		/***** FUNCTIONS *****/

		function placeFile(file, scale) {
			try {
				var idPlc = charIDToTypeID("Plc ");
				var desc2 = new ActionDescriptor();
				var idnull = charIDToTypeID("null");
				desc2.putPath(idnull, new File(file));
				var idFTcs = charIDToTypeID("FTcs");
				var idQCSt = charIDToTypeID("QCSt");
				var idQcsa = charIDToTypeID("Qcsa");
				desc2.putEnumerated(idFTcs, idQCSt, idQcsa);
				var idOfst = charIDToTypeID("Ofst");
				var desc3 = new ActionDescriptor();
				var idHrzn = charIDToTypeID("Hrzn");
				var idPxl = charIDToTypeID("#Pxl");
				desc3.putUnitDouble(idHrzn, idPxl, 0.000000);
				var idVrtc = charIDToTypeID("Vrtc");
				var idPxl = charIDToTypeID("#Pxl");
				desc3.putUnitDouble(idVrtc, idPxl, 0.000000);
				var idOfst = charIDToTypeID("Ofst");
				desc2.putObject(idOfst, idOfst, desc3);
				var idWdth = charIDToTypeID("Wdth");
				var idPrc = charIDToTypeID("#Prc");
				desc2.putUnitDouble(idWdth, idPrc, scale);
				var idHght = charIDToTypeID("Hght");
				var idPrc = charIDToTypeID("#Prc");
				desc2.putUnitDouble(idHght, idPrc, scale);
				var idAntA = charIDToTypeID("AntA");
				desc2.putBoolean(idAntA, true);
				executeAction(idPlc, desc2, DialogModes.NO);
			} catch (e) {}
		}

	}());

 

This presumes that the random background folder is named "random-bg" and is located on the desktop. 

 

As the script uses the place image command, to avoid sizing issues, the PPI values must be the same between the random background images and the various transparent PNG images. Both sets of images also had the same pixel width and height so positioning was not required.

 

I recorded the script into an action:

 

 

Note that I have included a step to move the active layer backwards, as the background image has to be behind the transparent image. I could have added this in the script, but took the easy path for this example.

 

I then used Image Processor Pro to run the action over the 12 images:

 

It works with the basic Image Processor script that is installed with Photoshop, however, I only had a successful result with PSD, using JPEG I had an incorrect result with only the background image being visible, which is why I used the Image Processor Pro script. One could also try the Batch command.

 

More could be done, I don't have much time tonight so this was the best that I could come up with.

 

hameedfarah
Known Participant
March 27, 2022

*The end result would be 1 JPG file for each PNG file...The total files would be only 500 which is the number of the PNG files 🙂

c.pfaffenbichler
Community Expert
Community Expert
March 27, 2022

@hameedfarah wrote:

*The end result would be 1 JPG file for each PNG file...The total files would be only 500 which is the number of the PNG files 🙂


Was that supposed to answer my request »Please provide a meaningful description of and file and folder structure and the naming conventions.«? 

Because it does not seem to do that. (edited)

 

Where are the two groups of files located, can that be coded into the Script or do you want to use File-/Folder-Selection-dialogs, where are the new files to be stored, how are they supposed to be named, …? 

hameedfarah
Known Participant
March 27, 2022

I don't want to make it harder really, the easiet possible solution and I will cope 🙂

If it's possible to choose the files or folders for the images, backgrounds and final outputs then great otherwise plesae assume the following

 

Input images are located in

H:\Product Photos\Designs\C001a.png

H:\Product Photos\Designs\C002a.png

H:\Product Photos\Designs\C003a.png

H:\Product Photos\Designs\C004a.png

....

H:\Product Photos\Designs\C500a.png

 

 

Backgrounds are located in 

H:\Product Photos\BK\bk (1).jpg

H:\Product Photos\BK\bk (2).jpg

H:\Product Photos\BK\bk (3).jpg

...

H:\Product Photos\BK\bk (20).jpg

 

 

The output will be in

H:\Product Photos\C001a.jpg

H:\Product Photos\C002a.jpg

H:\Product Photos\C003a.jpg

H:\Product Photos\C004a.jpg

...

H:\Product Photos\C500a.png

 

Please note that the number of PNGs and backgrounds is not always fixed

c.pfaffenbichler
Community Expert
Community Expert
March 27, 2022

Please provide a meaningful description of and file and folder structure and the naming conventions. 

 

How familiar are you with JavaScript and Photoshop’s DOM? 

hameedfarah
Known Participant
March 27, 2022

Unforutranetly I am not familiar with JavaScript but if provided with the script I can run it 🙂

 

As for the naming I am flexbile, the only thing that is needed for the original PNG name to stay the same in the end JPG file.

Ideally the PNG files would be named as per the SKUs which would be C001a.png for example (Letter and 3 digit sequntial number then letter)

The backgrounds are named 

bk (1).jpg 

bk (2).jpg 

bk (3).jpg

 

Many thanks for the help!