Skip to main content
Participant
November 29, 2010
Question

Copy paths from one document to another

  • November 29, 2010
  • 1 reply
  • 8765 views

Hi there,

There've been several discussions about this on ps-script.com and the Adobe forums.

But none of the supplied scripts did really satisfy my needs...

As sending files to Asia for clipping purposes becomes more and more common I think this could help a lot of people that don't want to spend their day copying paths from their JPG 5 compressed image to their own non-compressed TIF file or whatever...

So I have two images of identic canvas size, resolution,... and i want to transfer all paths from the one image to the other.

I've seen this script from Michael Hale and Christof Pfaffenbichler going around that basically copies every single path-point into an array that you can copy into your other image..


function extractSubPathInfo(pathObj){
   var derpfad = new Array();
   var pl = pathObj.subPathItems.length;
   for(var s=0;s<pl;s++){
      var pArray = new Array();
      for(var i=0;i<pathObj.subPathItems.pathPoints.length;i++){
         pArray = new PathPointInfo;
         pArray.kind = pathObj.subPathItems
.pathPoints.kind;
         pArray.anchor = pathObj.subPathItems
.pathPoints.anchor;
         pArray.leftDirection = pathObj.subPathItems
.pathPoints.leftDirection;
         pArray.rightDirection = pathObj.subPathItems
.pathPoints.rightDirection;
         };
      derpfad[derpfad.length] = new Array();
      derpfad[derpfad.length - 1] = new SubPathInfo();
      derpfad[derpfad.length - 1].operation = pathObj.subPathItems
.operation;
      derpfad[derpfad.length - 1].closed = pathObj.subPathItems
.closed;
      derpfad[derpfad.length - 1].entireSubPath = pArray;
      };
  
   return derpfad;
      };

That's a nice solution but also a very very slow one if you work with larger images that contain many anchorpoints.. (I usually have to deal with 60x40cm @ 300dpi - about 7000x5000px if you're non-metric and 5-10 paths on it that have estimated 500(?) anchor points.. this is just a guess.. but I think you know what i mean)

So copying every anchor point into this array takes about 20 seconds (2x3.2GHz QuadCore Intel Xeon.. so no, its not cause my Mac is too slow )

In addition to this (which wouldn't be THAT big problem... at least I don't have to do it all by myself...) the script seems to sometimes not recognize the whole path.. Some parts are just missing after copying the path to the other image..

So I tried to workaround the whole thing and not copy the paths into the other image - I wanted to copy the layers of the TIF file into the JPG (the one with the paths) and overwrite the TIF.

This is pretty fast, everything seemed to be ok, until I realized that my script couldn't handle Layersets.

This is it (it's not very smoothly written, but it does the job..)

var docRef = app.activeDocument;
var docJPG= app.activeDocument;

// Here I open the TIF that has the same name as the JPG but in a /TIF/ subdirectoy

var jpg = docRef.name;
var fname = docRef.name.split(".");

var fname1 = "";

for (var k = 0; k <= fname.length - 2; k++) {
     fname1 = fname1 + fname + ".";
     }

var fname2 = "TIF";
var fnamenew = fname1 + fname2;
var newpath = docRef.path + "/TIF/" + fnamenew;



var docRef = app.activeDocument;
var TIF = newpath;

var TIFShortcut = new File(TIF);
var docTIF = open(TIFShortcut);

// Check if the TIF is 16-bit - and change the JPG to that...

if(docTIF.bitsPerChannel != docJPG.bitsPerChannel) {
     app.activeDocument = docJPG;
          docJPG.bitsPerChannel = docTIF.bitsPerChannel;
     app.activeDocument = docTIF;
     }



// Transfer the layers from the TIF to the JPG

for(var i = docTIF.artLayers.length-1; i >= 0; i--){

docTIF.artLayers.duplicate(docRef);

}
// Close the TIF
docTIF.close(SaveOptions.DONOTSAVECHANGES);

// Then I delete the Background Layer that was originally the JPG file

var ebenen = docRef.artLayers.length-1;
docRef.artLayers[ebenen].remove();

// Set the bottom Layer as Background Layer

var ebenen = docRef.artLayers.length-1;
docRef.artLayers[ebenen].isBackgroundLayer = 1;


// And finally replace the TIF file in the /TIF/ folder

docRef.saveAs(new File(newpath),TiffSaveOptions);

docRef.close();

docRef = null;

So this is what i need:


Either a possibility to check for Layersets and copy them as well

OR

A better faster solution to copy all paths from one Image to another.

Please Adobe, implement something in CS6 (or even better in an update for CS5 ) to easily copy a whole path.

I hope you guys can help me (and I'm sure there are more people having the same issue...)

kind regards

derflow85

This topic has been closed for replies.

1 reply

c.pfaffenbichler
Community Expert
Community Expert
November 30, 2010

Wouldn’t changing

for(var i = docTIF.artLayers.length-1; i >= 0; i--){
 
docTIF.artLayers.duplicate(docRef);
 
}

to

for(var i = docTIF.layers.length-1; i >= 0; i--){
 
docTIF.layers.duplicate(docRef);
 
}

also work?

Edit: Another point:

Can you rely on the jpgs always having the same colorspace as the tiffs?

Maybe you should insert a check in your Script to make sure no accidental conversions can happen.

derflow85Author
Participant
November 30, 2010

Thanks for the answer. Haven't checked it, cause I already found a faster method to get the layers from one image to the other..

Plus I added a colormode and colorprofile check including conversion if they don't match. (thanks for that idea btw )

So if anybody wants to use it - feel free to do so.

Your directorys have to look like this:

ROOT (this is where the images with paths are in)

-file1.JPG

-file2.JPG

-file3.JPG

-TIF (this can also be a directory called "PSD" or "JPG" depending on what kind of files you usually work with)

--file1.TIF

--file2.TIF

--file3.TIF

I hope i could help somebody out there

kind regards

// Pfade übernehmen v2.1
// Copyright Thamer Florian
// 30.11.2010

var docRef = app.activeDocument;
var docJPG= app.activeDocument;


// Check for a "TIF","PSD","JPG" Subdirectory, which contains the Images where the paths should be applied to.


var checksum = "0";
for( var i = "1"; i <= "3"; i++){

if( i == "1" ) {
var newpath = docRef.path + "/TIF/";
newpath = new File(newpath);
if(newpath.exists) {
checksum++;
var dateityp = "TIF";
}
}

if( i == "2" ) {
var newpath = docRef.path + "/PSD/";
newpath = new File(newpath);
if(newpath.exists) {
checksum++;
var dateityp = "PSD";
}
}

if( i == "3" ) {
var newpath = docRef.path + "/JPG/";
newpath = new File(newpath);
if(newpath.exists) {
checksum++;
var dateityp = "JPG";
}
}

}

if( checksum > "1") alert("Fehler!\nBitte nur einen einzigen TIF, PSD oder JPG Unterordner erstellen"); // Error if there is more than one possible subdirectory
if( checksum < "1") alert("Fehler!\nKein TIF, PSD oder JPG Unterordner vorhanden"); // Error if there is no possible subdirectory



if( checksum == "1") { // The Script will only run if there is exacly ONE compatible subdirectory

// open the TIF/PSD/JPG file with the same name as the JPG

var jpg = docRef.name;
var fname = docRef.name.split(".");

var fname1 = "";

for (var k = 0; k <= fname.length - 2; k++) {
fname1 = fname1 + fname + ".";
}

var fnamenew = fname1 + dateityp;
var newpath = docRef.path + "/" + dateityp + "/" + fnamenew;

var docRef = app.activeDocument;
var TIF = newpath;

// Opening the TIF/PSD/JPG file
var TIFShortcut = new File(TIF);
if( !TIFShortcut.exists ) {
alert("Ups!\nDatei " + TIFShortcut + " nicht gefunden!\n" + jpg + " bleibt geöffnet"); // wenn die Datei nicht existiert Script beenden
}
else {
var docTIF = open(TIFShortcut);

// Check Resolution/Canvas size

app.activeDocument = docJPG;
if( docTIF.resolution != docJPG.resolution ) var sizeerr = "";
if( (docTIF.width != docJPG.width) || (docTIF.length != docJPG.length) ) var sizeerr = "";
if (sizeerr != null) {
alert("Dokumentgröße/Auflösung unterschiedlich!\nDie Datei " + jpg + " hat eine falsche Dokumentgröße/Auflösung.\nSie bleibt geöffnet");
docTIF.close();
}
else {
// Check color mode, color profile and bits per channel, and correct them
if( docTIF.mode != docJPG.mode ) docJPG.convertProfile(docTIF.colorProfileName, Intent.RELATIVECOLORIMETRIC, true, true);

if( docTIF.colorProfileName != docJPG.colorProfileName ) docJPG.colorProfileName = docTIF.colorProfileName;

if( docTIF.bitsPerChannel != docJPG.bitsPerChannel) docJPG.bitsPerChannel = docTIF.bitsPerChannel;


// So this is where i copy all the layers from the e.g. TIF to the JPG with paths

// I use the Select All Layers Command (cmd+alt+A - as far as i know not accessible through a menu)

// Problem is: It select all Layers EXCEPT the background layer

// So if there is a BG Layer i convert it to a normal layer first and rebackgroundize it afterwards.


app.activeDocument = docTIF;

var ebenen = docTIF.artLayers.length-"1";


if (docTIF.artLayers[ebenen].isBackgroundLayer == true) {
           docTIF.artLayers[ebenen].isBackgroundLayer = false;
           var hgset = "1";
}


// Select all layers
// =======================================================
var idselectAllLayers = stringIDToTypeID( "selectAllLayers" );
var desc14 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref8 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref8.putEnumerated( idLyr, idOrdn, idTrgt );
desc14.putReference( idnull, ref8 );
executeAction( idselectAllLayers, desc14, DialogModes.NO );

// DRAG all layers to the other document, this increases speed, cause nothing goes into clipboard

// and I don't copy layer by layer.

// =======================================================
var idDplc = charIDToTypeID( "Dplc" );
var desc50 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref40 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref40.putEnumerated( idLyr, idOrdn, idTrgt );
desc50.putReference( idnull, ref40 );
var idT = charIDToTypeID( "T " );
var ref41 = new ActionReference();
var idDcmn = charIDToTypeID( "Dcmn" );
ref41.putName( idDcmn, jpg ); // jpg = target document
desc50.putReference( idT, ref41 );
var idVrsn = charIDToTypeID( "Vrsn" );
desc50.putInteger( idVrsn, 5 );
executeAction( idDplc, desc50, DialogModes.NO );

// close the original TIF/PSD/JPG file
docTIF.close(SaveOptions.DONOTSAVECHANGES);

// delete the layer from the JPG file that has been in Asia :)

var ebenen = docRef.artLayers.length-1;
docRef.artLayers[ebenen].remove();

// set the bottom layer as background if it was before

if (hgset) {
           var ebenen = docRef.artLayers.length-1;
           docJPG.artLayers[ebenen].isBackgroundLayer = true;
}

// and finally overwrite TIF/PSD/JPG in the TIF/PSD/JPG subdirectory

switch( dateityp ) {
case("TIF"): docRef.saveAs(new File(newpath),TiffSaveOptions); break;
case("PSD"): docRef.saveAs(new File(newpath),PhotoshopSaveOptions); break;
case("JPG"): docRef.saveAs(new File(newpath),JPEGSaveOptions); break;
}
docRef.close();

}
}
}



Participant
June 8, 2011

Great script! Much thanks!

We often receive TIFs with alphamasks and paths, so a script that would work with tiff files instead of jpgs would be nice!