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

Get Layer Groups from C++ plugin

Explorer ,
Mar 16, 2013 Mar 16, 2013

Hi!

I'm trying to get next things:

1) layers hierarchy

2) layers bounds rect

3) save every layer to PNG file

--

Currently I can only get list of layers:

auto &layerInfo = globals->exportParamBlock->documentInfo->layersDescriptor;

for (int i = 0; i < layerN; ++i)

{

                    std::u16string utfStr = layerInfo->unicodeName;

  layerInfo = layerInfo->next;

}

Help me, please!

TOPICS
SDK
3.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

correct answers 1 Correct answer

Participant , Mar 17, 2013 Mar 17, 2013

In the SDK take a look at

X:\.....\AdobeCSY_SDK\samplecode\automation\listner\

X:\.....\AdobeCSY_SDK\samplecode\automation\getter\

Compile the plugins in debug mode and place them in photoshop plugin folder.

Listner creates C++ function for every action that you do in Photoshop (select layer, save file, copy, paste, make new doc etc.)

C++ functions are in listner.log That is text file and ... Listner is magician

His partner is getter you call it ftom meny in photoshop I think  file>automate>getter

Tak

...
Translate
Adobe
Participant ,
Mar 16, 2013 Mar 16, 2013

Within automation plugin we are traversing layer accessing them using index.

however to decide whether a layer is a real layer or just layer set start or stop we use following routine:

SPErr AMAutoPlugin::GetLayerSetInfo(int index, int * result)

{

    SPErr error = kSPNoError;

    char layertype[1024]="";

    char cdata1[1024]="";

    char cdata2[1024]="";

    DescriptorTypeID runtimeKeyID;

    uint32 data1;

    uint32 data2;

    error = sPSActionControl->StringIDToTypeID("layerSection", &runtimeKeyID);

    if (error) goto returnError;

    error = PIUGetInfoByIndex(index, classLayer,runtimeKeyID, &data1, &data2);

    if (error) goto returnError;

    error = sPSActionControl->TypeIDToStringID(data1,cdata1,255);

    if (error) goto returnError;

    error = sPSActionControl->TypeIDToStringID(data2,cdata2,255);

    if (error) goto returnError;

    if (strcmp(cdata1, "layerSectionStart")==0)*result=2;

    else if (strcmp(cdata1, "layerSectionEnd")==0)*result=1;

    else if (strcmp(cdata1, "layerSectionContent")==0)*result=0;

    else *result =-1;

returnError:

     return error;

}  

It is old and not to safe but i think you will get the picture.

To get layer bounds use something like (Part of the saving routine):

AUTO_ERROR AMAutoPlugin::SaveClipFromLayer(int LayerCounter, char* path_buffer, string &sErrorString )

{

    .......

    DescriptorTypeID runtimeKeyID;

    DescriptorTypeID runtimeClassID;

    DescriptorClassID descClass;

    PIActionDescriptor descLayer = NULL;

    PIActionDescriptor descPosition = NULL;

    double top= 0;

    double left= 0;

    double bottom= 0;

    double right= 0;

     AUTO_ERROR autoError =AUTO_OK;

    SPErr error =kSPNoError;

........

     error = sPSActionDescriptor->Make(&descLayer);

    if (error) goto returnAutoError;

    error = sPSActionDescriptor->Make(&descPosition);

    if (error) goto returnAutoError;

    error =SelectLayerByIndex( LayerCounter);

    if (error!=-1 && error!=0){

        autoError=ERR_SELECT_LAYER_BYINDEX;

        goto returnAutoError;

    }

     //

    // GET LAYER BOUNDS

    //

    error = PIUGetInfoByIndex(LayerCounter,classLayer,0,&descLayer,NULL);

    if (error) goto returnAutoError;

    error = sPSActionControl->StringIDToTypeID("bounds", &runtimeKeyID);

         if (error) goto returnAutoError;

    error = sPSActionControl->StringIDToTypeID("classRectangle", &runtimeClassID);

        if (error) goto returnAutoError;

    error = PIUGetSingleItemFromDescriptor(descLayer,runtimeKeyID,&descPosition,&descClass);

    if (error) goto returnAutoError;

    error = sPSActionDescriptor->GetFloat(descPosition, keyTop, &top);

    if (error) goto returnAutoError;

    error = sPSActionDescriptor->GetFloat(descPosition, keyLeft, &left);

    if (error) goto returnAutoError;

    error = sPSActionDescriptor->GetFloat(descPosition, keyBottom, &bottom);

    if (error) goto returnAutoError;

    error = sPSActionDescriptor->GetFloat(descPosition, keyRight, &right);

    if (error) goto returnAutoError;

......

returnAutoError:

     // do error handling in this case we are calling our AddErrorDescription function

     // clean something ...

    if (descLayer != NULL) sPSActionDescriptor->Free(descLayer);

    if (descPosition != NULL) sPSActionDescriptor->Free(descPosition);

    autoError=AddErrorDescription(sErrorString, autoError,LayerCounter, 2);

    return     autoError;   

...

}

Saving PNG (made from listner plugin)

SPErr AMAutoPlugin::SavePNGALPHA(char *FullPath, bool SaveAlpha)

{

     SPErr error = kSPNoError;

     PIActionDescriptor result = NULL;

     PIActionDescriptor FileDesc = NULL;

     PIActionDescriptor FileTypeDesc = NULL;    

     Handle aliasValue = NULL;

     error = sPSActionDescriptor->Make(&FileDesc);

     if (error) goto returnError;

     error = sPSActionDescriptor->Make(&FileTypeDesc);

     if (error) goto returnError;

     error = sPSActionDescriptor->PutEnumerated(FileTypeDesc, keyPNGInterlaceType, typePNGInterlaceType, enumPNGInterlaceNone);

     if (error) goto returnError;

     error = sPSActionDescriptor->PutEnumerated(FileTypeDesc, keyPNGFilter, typePNGFilter, enumPNGFilterAdaptive);

     if (error) goto returnError;

     error = sPSActionDescriptor->PutObject(FileDesc, keyAs, classPNGFormat, FileTypeDesc);

     if (error) goto returnError;

     FullPathToAlias(FullPath, aliasValue);

     error = sPSActionDescriptor->PutAlias(FileDesc, keyIn, aliasValue);

     if (error) goto returnError;

     error = sPSActionDescriptor->PutBoolean(FileDesc, keyCopy, true);

     if (error) goto returnError;

     error = sPSActionDescriptor->PutBoolean(FileDesc, keyLowerCase, true);

     if (error) goto returnError;

     error = sPSActionDescriptor->PutBoolean(FileDesc, keyAlphaChannels, SaveAlpha);

     if (error) goto returnError;

     error = sPSActionControl->Play(&result, eventSave, FileDesc, plugInDialogSilent);

     if (error) goto returnError;

returnError:

     if (result != NULL) sPSActionDescriptor->Free(result);

     if (FileDesc != NULL) sPSActionDescriptor->Free(FileDesc);

     if (FileTypeDesc != NULL) sPSActionDescriptor->Free(FileTypeDesc);

     if (aliasValue != NULL) sPSHandle->Dispose(aliasValue);

     return error;

}

Use getter plugin (its source is in SDK examples automation section) to se how PS stores info about everything in it

(ok not everything but close), it saves data in getter.log

buy the way it should be called putter because ... you will se from log file

Use listner (also automation plugin in SDK examples) to make  you a code for the command that you have

performed in PS

Hope this help.

Regards,

Momir Zecevic

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
Explorer ,
Mar 17, 2013 Mar 17, 2013

thanks a lot!

But I want this functionality in export plugin, not automation one.

Is that possible?

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
Participant ,
Mar 17, 2013 Mar 17, 2013

12 years ago when written my first plugin it was impossible.

Fie format plugins (import/export) was ment to import export single file.

I also needed to export each layer into separate file and thus ended in automation plugin.

From that time maybe something has changed i file format plugins i dont know.

Regards,

Momir

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
Explorer ,
Mar 17, 2013 Mar 17, 2013

Ok. I don't understand how do you create such code, this is some magic..

SelectLayerByIndex is missing. Can you tell me how to do that?

And also, how I can get Layer's name (utf16) and how much layers is in document?

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
Participant ,
Mar 17, 2013 Mar 17, 2013

In the SDK take a look at

X:\.....\AdobeCSY_SDK\samplecode\automation\listner\

X:\.....\AdobeCSY_SDK\samplecode\automation\getter\

Compile the plugins in debug mode and place them in photoshop plugin folder.

Listner creates C++ function for every action that you do in Photoshop (select layer, save file, copy, paste, make new doc etc.)

C++ functions are in listner.log That is text file and ... Listner is magician

His partner is getter you call it ftom meny in photoshop I think  file>automate>getter

Take a look at getter.log

Modify the code to suite you.

Regards,

Momir

PS

SPErr AMAutoPlugin::SelectLayerByIndex( uint32 value)

{

    SPErr error = kSPNoError;

   

    DescriptorClassID desiredClass=classLayer;

    error = PIUSelectByIndex(desiredClass, value);

    if (error) goto returnError;

returnError:

    return error;

}

Modified minorely from listner.log

By the way if you debug listner it self you will se underlying mechanisms

of getting subscibed to events, how thw events are handled etc.

Debuging getter is priceles since you will se that there are many ways to get info from PS.

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 Beginner ,
Nov 07, 2023 Nov 07, 2023
LATEST

HI
Is there any way we can save the document image as png or in binary format if the color mode is cmyk.

I would really appreciate any thoughts/suggestions on the matter.

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