Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Automating Product Image Creation

New Here ,
Sep 20, 2019 Sep 20, 2019

Hi all,

 

I work for a company that sells custom apparel. We rely on photoshop to create product images by pasting the product design/company logo onto our stock images of garments. This often requires scaling the logo, warping it, and placing it the image of the garment to make it look as realistic as possible. 

 

For each client, we create 30-40 different products, and applying the logo to each product is a pretty time consuming process. I've looked into possibly using the actions feature to edit all the images at once, however it doesn't work because the logos are placed in different locations on each product and are often different sizes (example: big logo across the chest vs. a small logo on one pectoral). 

 

Does anyone know of a way that we could automate some of the creation of these product images? Maybe something where we could designate the location and size where the logo should be for each product and then batch add the logo to each image in the designated size and location? Any advice would be much appreciated!

TOPICS
Actions and scripting
2.0K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Participant ,
Sep 20, 2019 Sep 20, 2019

I think this is so hard since you don't have a rule for that... 

With actions you could create an action with all the process and just select the box besides the process tat refer to resize the image, so as to resize manually and once you set enter the action would keep going, but you still would need to resize manually. But you could open all documents, insert the logo, save and close the document automatically at least.

 

Better than that I think that just if you wrote a script for that, and even so depending on how different logos are placed between different images it could be hard... 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 20, 2019 Sep 20, 2019

Try JJMack's "BatchMockupTemplates.jsx" script here:

 

http://www.mouseprints.net/old/dpr/PhotoCollageToolkit.html

 

Otherwise search the forum, this comes up every month and there are new scripts created and existing scripts referenced in many topic threads.

 

Good luck!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 24, 2019 Sep 24, 2019

The issue I'm having with that script is that it looks like its inserting multiple images into the same template. What I'm looking to do is insert the same image into multiple templates. I've attached an image of what I'm looking to do. SamplePhotoshopWork.jpg

I have blank product images like the two shirts above and I want to apply something like that Eagles logo to that navy t-shirt, that grey quarterzip, and 60 more different blank product images. As you can see above, some products require the logo to be scaled/adjusted to different sizes depending on the product. 

 

Plus, right now all the blank product images are just jpegs. I'm assuming I would need to convert them all to .psd's. I'm sure there's some way to do this and I've been looking everywhere. 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 25, 2019 Sep 25, 2019
LATEST

A single or multiple images can be inserted using JJMacks scripts.

 

JJMack offers at least two single image scripts – BatchOneImageCollage.jsx & BatchReplaceOneObject.jsx

 

You are correct, this is one product template at a time, however there could be 2 or 2000+ different logos going onto the same template image...

 

_____________

 

OK, you mention the case of working one set/fixed logo at a time and applying it to 1, 2 or 2000+ different templates.

 

That should be easy to do as well...

 

The template file would have 2 horizontal and 2 vertical guides creating a bounding area for the logo position.

 

I'd record an action that placed a generic named logo from a static location (this logo can be changed as needed using the same name without breaking the action). I would then record a step that played an installed script to FitImageToGuides.jsx (code below) to resize proportionally to the guides. At a minimum, the action would only need 2 steps.

 

Of course, you may need to make it look more realistic by adding displacement maps, shading etc.

 

This can be bulk run using a folder containing multiple logos using the batch action or image processor or image processor pro scripts.

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

 

P.S. If you search the forum, you will find many similar requests to your from other apparel and other product production artists, this must come up at least once per month.

_____________

 

 

// forums.adobe.com/message/8732179#8732179
// forums.adobe.com/message/8728770#8728770

// 2019 - Uncomment line 123 to enable the layer mask, which has been disabled to retain the proportions of the resized layer

// FitImageToGuides.jsx

/* ========================================================== 
// 2014  John J. McAssey (JJMack)  
// ======================================================= */  
  
  
// This script is supplied as is. It is provided as freeware.   
// The author accepts no liability for any problems arising from its use.  
  
  
/* Help Category note tag menu can be used to place script in automate menu 
<javascriptresource> 
<about>$$$/JavaScripts/FitImageToGuides/About=JJMack's FitImageToGuides .^r^rCopyright 2014 Mouseprints.^r^rFour and only four guides are required</about> 
<category>JJMack's Script</category> 
</javascriptresource> 
*/  
  
  
// enable double-clicking from Mac Finder or Windows Explorer  
#target photoshop  
  
  
// bring application forward for double-click events  
app.bringToFront();  
  
  
// ensure at least one document open  
if (!documents.length) alert('There are no documents open.', 'No Document');  
else {  
  // declare Global variables  
  
  
  //main(); // at least one document exists proceed  
  app.activeDocument.suspendHistory('Fix Image to Guides','main()');  //problem if there is a selection a layer resize Photoshop back up a history step ?  
}  
///////////////////////////////////////////////////////////////////////////////  
//                            main function                               
///////////////////////////////////////////////////////////////////////////////  
function main() {  
  // declare local variables  
  var orig_ruler_units = app.preferences.rulerUnits;  
  var orig_type_units = app.preferences.typeUnits;  
  var orig_display_dialogs = app.displayDialogs;  
  app.preferences.rulerUnits = Units.PIXELS; // Set the ruler units to PIXELS  
  app.preferences.typeUnits = TypeUnits.POINTS;   // Set Type units to POINTS  
  app.displayDialogs = DialogModes.NO; // Set Dialogs off  
  try { code(); }  
  // display error message if something goes wrong  
  catch(e) { alert(e + ': on line ' + e.line, 'Script Error', true); }  
  app.displayDialogs = orig_display_dialogs; // Reset display dialogs   
  app.preferences.typeUnits  = orig_type_units; // Reset ruler units to original settings   
  app.preferences.rulerUnits = orig_ruler_units; // Reset units to original settings  
}  
///////////////////////////////////////////////////////////////////////////////  
//                           main function end                              
///////////////////////////////////////////////////////////////////////////////  
  
  
///////////////////////////////////////////////////////////////////////////////////////////////  
// The real code is embedded into this function so that at any point it can return   
// to the main line function to let it restore users edit environment and end        
//////////////////////////////////////////////////////////////////////////////////////////////  
function code() {  
  if (app.activeDocument.guides.length != 4) { alert("Four and only four Guides are required"); return; } // quit  
  // get guides;  
  var theVert = new Array;  
  var theHor = new Array;  
  for (var m = 0; m < app.activeDocument.guides.length; m++) {  
  if (app.activeDocument.guides[m].direction == Direction.HORIZONTAL) {theVert.push(app.activeDocument.guides[m].coordinate)}  
  else {theHor.push(app.activeDocument.guides[m].coordinate)}  
    };  
  if (theHor.length != 2 || theVert.length != 2) { alert("Four Guides two vertical and two horizontal are required"); return; } // quit  
  getTarget=getSelectedLayersIdx();  
  if (getTarget.length!=1){ alert("The number of layers targeted is " + getTarget.length ); return; } // quit  
  if (app.activeDocument.activeLayer.isBackgroundLayer ) { alert("Can not resize the background layer"); return; } // quit  
  if (!app.activeDocument.activeLayer.visible ) { alert("Active layer is  not visible"); return; } // quit  
  //if (hasLayerMask()) { alert("Active layer is  Masked"); return; } // quit  
  if (app.activeDocument.activeLayer.kind == LayerKind.NORMAL  || app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT && hasLayerMask()) { deleteLayerMask ();}  
  if (app.activeDocument.activeLayer.kind != LayerKind.NORMAL  && app.activeDocument.activeLayer.kind != LayerKind.SMARTOBJECT )  {   
  alert("Active layer is " + app.activeDocument.activeLayer.kind); return; } // quit  
  // set selection to the area defined but the guide lines the selection may get undone by the bug in .resize() backing up a step in histoty ???  
  app.activeDocument.selection.select([[theHor[0], theVert[0]], [theHor[1], theVert[0]], [theHor[1], theVert[1]], [theHor[0], theVert[1]]]);  
  // resize current normal layer or smart object layer to just cover selection canvas area aspect ratio and size and mask off any overflow  
  var SB = app.activeDocument.selection.bounds; // Get selection bounds  
  var SWidth = (SB[2].value) - (SB[0].value); // Area width  
  var SHeight = (SB[3].value) - (SB[1].value); // Area height  
  var LB = app.activeDocument.activeLayer.bounds; // Get Active layers bounds  
  var LWidth = (LB[2].value) - (LB[0].value); // Area width  
  var LHeight = (LB[3].value) - (LB[1].value); // Area height  
  var userResampleMethod = app.preferences.interpolation; // Save interpolation settings  
  app.preferences.interpolation = ResampleMethod.BICUBIC; // resample interpolation bicubic  
  app.activeDocument.selection.deselect(); // This deselect work around Adobe Bug in CS5, CS6, CC and CC 2014  
  // Since Adobe does not fix old releases of Photoshop this is a necessary work around for many releases of Photoshop  
  //alert("Before re-size history");  // Added to debug Adobe Resize Bug  
  try {  
  if (LWidth/LHeight<SWidth/SHeight) { // layer's Aspect Ratio less the Canvas area Aspect Ratio   
  var percentageChange = ((SWidth/LWidth)*100); // Resize to canvas area width  
  app.activeDocument.activeLayer.resize(percentageChange,percentageChange,AnchorPosition.MIDDLECENTER);  
  }  
  else {   
  var percentageChange = ((SHeight/LHeight)*100); // resize to canvas area height  
  app.activeDocument.activeLayer.resize(percentageChange,percentageChange,AnchorPosition.MIDDLECENTER);  
  }  
  }  
  catch(e) {   
  app.preferences.interpolation = userResampleMethod; // Reset interpolation setting  
  selectFront(); // Photoshop make top layer current when none are targeted  
  code(); // Retry  with top visible layer selected targeted   
  return; // rest would have been done during the retry  
  }  
  //alert("After re-size history");    // Added to debug Adobe Resize Bug  
  app.preferences.interpolation = userResampleMethod; // Reset interpolation setting  
  // Seems to be a bug in  resize() the document seems to first be backed up a step in history  
  app.activeDocument.selection.select([[theHor[0], theVert[0]], [theHor[1], theVert[0]], [theHor[1], theVert[1]], [theHor[0], theVert[1]]]); // redo the selection  
  align('AdCH'); // align to horizontal centers  
  align('AdCV'); // align to vertical centers  
  // addLayermask(); // add layer mask to mask off excess
}  
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
// Helper Functions  
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
function align(method) {  
  var desc = new ActionDescriptor();  
  var ref = new ActionReference();  
  ref.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );  
  desc.putReference( charIDToTypeID( "null" ), ref );  
  desc.putEnumerated( charIDToTypeID( "Usng" ), charIDToTypeID( "ADSt" ), charIDToTypeID( method ) );  
  try{executeAction( charIDToTypeID( "Algn" ), desc, DialogModes.NO );}  
  catch(e){}  
}  
///////////////////////////////////////////////////////////////////////////////     
// Function: hasLayerMask     
// Usage: see if there is a raster layer mask     
// Input: <none> Must have an open document     
// Return: true if there is a vector mask     
///////////////////////////////////////////////////////////////////////////////     
function hasLayerMask() {     
  var hasLayerMask = false;     
  try {     
  var ref = new ActionReference();     
  var keyUserMaskEnabled = app.charIDToTypeID( 'UsrM' );     
  ref.putProperty( app.charIDToTypeID( 'Prpr' ), keyUserMaskEnabled );     
  ref.putEnumerated( app.charIDToTypeID( 'Lyr ' ), app.charIDToTypeID( 'Ordn' ), app.charIDToTypeID( 'Trgt' ) );     
  var desc = executeActionGet( ref );     
  if ( desc.hasKey( keyUserMaskEnabled ) ) { hasLayerMask = true; }     
  }  
  catch(e) { hasLayerMask = false; }     
  return hasLayerMask;     
}     
function getSelectedLayersIdx(){  
      var selectedLayers = new Array;  
      var ref = new ActionReference();  
      ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );  
      var desc = executeActionGet(ref);  
      if( desc.hasKey( stringIDToTypeID( 'targetLayers' ) ) ){  
         desc = desc.getList( stringIDToTypeID( 'targetLayers' ));  
          var c = desc.count  
          var selectedLayers = new Array();  
          for(var i=0;i<c;i++){  
            try{  
               activeDocument.backgroundLayer;  
               selectedLayers.push(  desc.getReference( i ).getIndex() );  
            }catch(e){  
               selectedLayers.push(  desc.getReference( i ).getIndex()+1 );  
            }  
          }  
       }else{  
         var ref = new ActionReference();  
         ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "ItmI" ));  
         ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );  
         try{  
            activeDocument.backgroundLayer;  
            selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" ))-1);  
         }catch(e){  
            selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" )));  
         }  
      }  
      return selectedLayers;  
};  
function selectFront() {  
// Alt+. shortcut select ftont visible layer  
var idslct = charIDToTypeID( "slct" );  
    var desc250 = new ActionDescriptor();  
    var idnull = charIDToTypeID( "null" );  
        var ref207 = new ActionReference();  
        var idLyr = charIDToTypeID( "Lyr " );  
        var idOrdn = charIDToTypeID( "Ordn" );  
        var idFrnt = charIDToTypeID( "Frnt" );  
        ref207.putEnumerated( idLyr, idOrdn, idFrnt );  
    desc250.putReference( idnull, ref207 );  
    var idMkVs = charIDToTypeID( "MkVs" );  
    desc250.putBoolean( idMkVs, false );  
executeAction( idslct, desc250, DialogModes.NO );  
}  
function deleteLayerMask (apply) {  
// Delet Layer mask default to not apply first  
if (apply == undefined) {var apply = false};  
try {  
var idDlt = charIDToTypeID( "Dlt " );  
    var desc9 = new ActionDescriptor();  
    var idnull = charIDToTypeID( "null" );  
        var ref5 = new ActionReference();  
        var idChnl = charIDToTypeID( "Chnl" );  
        var idChnl = charIDToTypeID( "Chnl" );  
        var idMsk = charIDToTypeID( "Msk " );  
        ref5.putEnumerated( idChnl, idChnl, idMsk );  
    desc9.putReference( idnull, ref5 );  
    var idAply = charIDToTypeID( "Aply" );  
    desc9.putBoolean( idAply, apply );  
executeAction( idDlt, desc9, DialogModes.NO );  
}  
catch (e) {}  
};  
function addLayermask(){  
// Add layer Mask  
var idMk = charIDToTypeID( "Mk  " );  
    var desc52 = new ActionDescriptor();  
    var idNw = charIDToTypeID( "Nw  " );  
    var idChnl = charIDToTypeID( "Chnl" );  
    desc52.putClass( idNw, idChnl );  
    var idAt = charIDToTypeID( "At  " );  
        var ref19 = new ActionReference();  
        var idChnl = charIDToTypeID( "Chnl" );  
        var idChnl = charIDToTypeID( "Chnl" );  
        var idMsk = charIDToTypeID( "Msk " );  
        ref19.putEnumerated( idChnl, idChnl, idMsk );  
    desc52.putReference( idAt, ref19 );  
    var idUsng = charIDToTypeID( "Usng" );  
    var idUsrM = charIDToTypeID( "UsrM" );  
    var idRvlS = charIDToTypeID( "RvlS" );  
    desc52.putEnumerated( idUsng, idUsrM, idRvlS );  
executeAction( idMk, desc52, DialogModes.NO );  
// Un link layer mask just added fron the layers content  
var idsetd = charIDToTypeID( "setd" );  
    var desc2 = new ActionDescriptor();  
    var idnull = charIDToTypeID( "null" );  
        var ref1 = new ActionReference();  
        var idLyr = charIDToTypeID( "Lyr " );  
        var idOrdn = charIDToTypeID( "Ordn" );  
        var idTrgt = charIDToTypeID( "Trgt" );  
        ref1.putEnumerated( idLyr, idOrdn, idTrgt );  
    desc2.putReference( idnull, ref1 );  
    var idT = charIDToTypeID( "T   " );  
        var desc3 = new ActionDescriptor();  
        var idUsrs = charIDToTypeID( "Usrs" );  
        desc3.putBoolean( idUsrs, false );  
    var idLyr = charIDToTypeID( "Lyr " );  
    desc2.putObject( idT, idLyr, desc3 );  
executeAction( idsetd, desc2, DialogModes.NO );  
}
  app.activeDocument.selection.deselect(); 

 

 

 

 

 

 

 

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines