Copy link to clipboard
Copied
Hi All,
I have a PSD file that contains several layers (a.k.a. ArtLayer in ExtendScript).
Each ArtLayer contains a single graphic image.
I would like to write an ExtendScript that:
* Opens the PSD file (I have that working)
* Iterates over the ArtLayers (I have that working)
* Finds the graphic image in the layer/finds the bounds of the single graphic image in the layer.
* Replaces the layer's original image with a new image of equal size and dimension.
Is this possible?
Many thanks,
John
Copy link to clipboard
Copied
From what I'm reading, yes. But, to make sure I have a few questions first.
1. Are these specific images or random?
2. When you replace them, are you replacing each size with a specific image? What I mean is, say the image on the layer is 200x200 pixels. Would this be replaced by an image that would be specifically for that size or do you have multiple images that could replace this one? So if another psd were opened and one of those layers had an image size of 200x200 pixels, it would use the same file. Or, would the script have to find another image file of the same size to replace that one with?
3. Are these images in the layers set up with transparent background so that there are no other pixels on that layer other than the image itself?
If "Yes" to all 3, then I believe it could be done.
Copy link to clipboard
Copied
Hi. Thank you for the quick reply. Here are my answers to your thoughtful questions:
>>>1. Are these specific images or random?
Each layer will contain only a single image, but its placement will vary. For example, let say I open myFile.psd and it contains 2 layers. Layer 1 will contain a single image located at some X,Y and be so wide and so high. Layer 2 will also contain a single image, located at some A, B and be of a certain width and height. Since each layer contains only a single image, I can simple clear the layer. From ExtendScript, this would be a myLayer.clear() call.
>>>2. When you replace them, are you replacing each size with a specific image? What I mean is, say the image on the layer is 200x200 pixels. Would this be replaced by an image that would be specifically for that size or do you have multiple images that could replace this one? So if another psd were opened and one of those layers had an image size of 200x200 pixels, it would use the same file. Or, would the script have to find another image file of the same size to replace that one with?
I would replace the original image with one of exactly the same dimensions. So, from my answer in #1, I could do something like this:
var myOrigBounds = myLayer.bounds;
myLayer.clear();
// PUT NEW IMAGE INTO THE LAYER (this is what I am struggling with)
>>>3. Are these images in the layers set up with transparent background so that there are no other pixels on that layer other than the image itself?
Yes, but that shouldn't matter, because I am going to clear() the original image anyway.
>>>If "Yes" to all 3, then I believe it could be done.
In essence, I believe the answer to all three is "yes" -- so, what I am looking for is how to best "put" the new image into the layer. The ArtLayer object does not seem to support a "paste" function or something similar.
Thanks for your help,
John
Copy link to clipboard
Copied
You are correct, ArtLayer does not support paste, but Document does. It allows you to paste into a selection.
app.activeDocument.paste(TRUE);
The TRUE will paste the contents of the clipboard into a selection if one exists. Otherwise, it will create a new layer and paste into that.
You can get the selection bounds from the ArtLayer bounds to paste into.
This should work for you. If not, post again and I'll work up a script unless Michael or xbytor gets here with one first. They always seem to beat me at writing scirpts.
Copy link to clipboard
Copied
This might be easier. It works with PDF's saved by Photoshop.
Open the PDF,
Convert each layer you want to replace into a smart object.
Replace the contents of that smart object with the new image.
That way there is no need to worry about where the image is on the layer as long as the replacement is the same size.
I can post the code for working with smart objects if you need it or you can use scriptlistner. Or if you have Configurator you can get the code from there.
Copy link to clipboard
Copied
Michael,
Thanks for your reply.
I am brand new to Photoshop, so I don't even know what a smart object is; however, it sounds promising. Please send or post the code to work with smart objects. I appreciate your help.
John
Copy link to clipboard
Copied
Thanks to everyone for the (very quick) replies. Much appreciated.
I will post my final code, once I get it all working.
Best,
John
Copy link to clipboard
Copied
Michael L Hale wrote:
This might be easier. It works with PDF's saved by Photoshop.
Open the PDF,
Convert each layer you want to replace into a smart object.
Replace the contents of that smart object with the new image.
That way there is no need to worry about where the image is on the layer as long as the replacement is the same size.
I can post the code for working with smart objects if you need it or you can use scriptlistner. Or if you have Configurator you can get the code from there.
That's an interesting approach. Can the smart object be replaced by a file without first opening that file? Or do you still have to open up the replacement image and copy-paste it into the smart object?
I don't work with smart objects much. My extent is setting up a smart object so I can run a filter on it or Shadows/Highlights and go back and readjust later if necessary.
I was thinking that since you already have the bounds of the image in the layer to figure out the size, just make your selection path from that and paste into. Or am I missing something?
Copy link to clipboard
Copied
Here are the functions. You may need to localize the error string in the second function.
As long as the images are the same size don't need to open the new image first. If not you would need to get the layer bounds, open the new image and resize to those bounds, and then save or saveAS the file. You wouldn't have to copy, switch docs, paste, and translate.
function makeSmartObject(){
//converts the current activeDocument.activeLayer to smart object
//Note works on layer or layerSet or background
//also works if more than one layer selected
executeAction( stringIDToTypeID( "newPlacedLayer" ), undefined, DialogModes.NO );
}function replaceLayer(fileRef){
//useage replaceLayr('/c/temp/new.jpg');
//replaces the current activeDocument.activeLayer
try {
var desc = new ActionDescriptor();
desc.putPath( charIDToTypeID( "null" ), new File( fileRef ) );
executeAction( stringIDToTypeID( "placedLayerReplaceContents" ), desc, DialogModes.NO );
} catch (e) {
if (!e.toString().match(/Replace Contents.+is not currently available/)) {
throw e;
};
};
}
Copy link to clipboard
Copied
Hi,
I took over this for John who had started this thread. I tried to implement the sample code provided for smart object for our need. I started with a very easy application just to get it working. I get an exception on the executeAction line in the replaceLayer function. Below in blue is the exception description. The 2 psd files referred to do exists. I'm using CS4. Any ideas what I did wrong would be appreciated.
I'll keep trying to solve the issue on my own and will edit this post if I do.
Error: General photoshop error occured. The functionality may not be available in this version of photshop.
Could not replace the smart objects because of a programming error.
function makeSmartObject( )
{
executeAction(stringIDToTypeID("newPlacedLayer"), undefined, DialogModes.NO);
}
function replaceLayer(fileRef)
{
try {
var desc = new ActionDescriptor();
desc.putPath(charIDToTypeID("null"), new File(fileRef));
executeAction(stringIDToTypeID("placedLayerReplaceContents", desc, DialogModes.NO));
} catch (e) {
throw e;
}
}
var fileRef = File("/c/users/steve/desktop/searchandise/photoshop templates/sandbox.psd");
var docRef1 = app.open(fileRef);
docRef1.activeLayer = docRef1.layers["ProductImage"];
makeSmartObject ();
replaceLayer ( "/c/users/steve/desktop/searchandise/photoshop templates/image_only.psd");
Copy link to clipboard
Copied
It looks like someone edited my function, which is ok with me. But
executeAction(stringIDToTypeID("placedLayerReplaceContents", desc, DialogModes.NO));
slould be
executeAction(stringIDToTypeID("placedLayerReplaceContents"), desc, DialogModes.NO));
Copy link to clipboard
Copied
Mea culpa, mea maximus culpa.
It wasn't so much my editing of your function as typing it in from a printout. A procedure fraught with dangers. This was just a quick and dirty (too dirty) test so I left off the comments to save time until I write the end product.
Thanks so much for the correction, I could have looked at that for a hundred years and never seen the obvious typo.
With the correction it worked like a charm.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now