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

Programmatically Replacing an Image in ArtLayer

New Here ,
Aug 20, 2009 Aug 20, 2009

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

TOPICS
Actions and scripting
4.4K
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
Engaged ,
Aug 20, 2009 Aug 20, 2009

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.

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 ,
Aug 20, 2009 Aug 20, 2009

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

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
Engaged ,
Aug 20, 2009 Aug 20, 2009

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.

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
Guru ,
Aug 20, 2009 Aug 20, 2009

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.

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 ,
Aug 20, 2009 Aug 20, 2009

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

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 ,
Aug 20, 2009 Aug 20, 2009

Thanks to everyone for the (very quick) replies. Much appreciated.

I will post my final code, once I get it all working.

Best,

John

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
Engaged ,
Aug 20, 2009 Aug 20, 2009

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?

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
Guru ,
Aug 20, 2009 Aug 20, 2009

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;
      };
  };
}

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 ,
Aug 31, 2009 Aug 31, 2009

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");

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
Guru ,
Aug 31, 2009 Aug 31, 2009

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));

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 ,
Aug 31, 2009 Aug 31, 2009
LATEST

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.

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