Overblog Suivre ce blog
Editer la page Administration Créer mon blog
/ / /

Quand on travaille sur plusieurs calques, et en particulier pour une illustration, il est pénible à chaque changement de calque de resélectionner la bonne brosse pour ce calque avec le bon diamètre, les bonnes couleurs d'avant et d'arrière plan, etc...

Par exemple le calque de dessin utilise sans doute une brosse ronde petite et noire (blanche pour les corrections), alors qu'un calque pour la couleur utilisera par exemple une brosse floue et large avec des couleurs quelconques.

Avec un ou deux calques de dessin et de nombreux calques pour la couleur que l'on modifient tous plus ou moins en même temps, les changements et règlages de brosses et de couleurs deviennent vite harassants.  

 

Bref il serait bien utile que le simple changement de calque restaure tous ces paramètres automatiquement, et qu'ils soient enregistrés à la sauvegarde du document, pour être retrouvés à la prochaine ouverture.

Il faudrait donc créer un contexte pour chaque calque.

 

C'est l'objet de ce script.

Il est en deux parties :

- la première doit être copiée dans un fichier INSTALL.JSX et permet d'installer les évènements Photoshop auxquels le script va réagir.

- la deuxième doit être copiée dans un fichier LAYERCTX.JSX du même répertoire .

 

En premier lieu, installer le script en exécutant INSTALL.JSX dans Photoshop par Fichier>Scripts>Parcourir.

 

Dès l'ouverture d'un nouveau document ou l'utilisation du document courant , le script demandera si les contextes de calques doivent être créés pour ce document. La réponse NON laisse définitivement le document tranquille (pas de contextes). La réponse OUI enregistre les informations de contexte dans les méta-données du document. Ses contextes seront gèrés à chaque ouverture (si le script est actif bien-sûr).

 

Quand les contextes sont gèrés, la liste des brosses est sauvegardée à la fermeture du document dans un fichier (.ABR) de même nom que le document, et restaurée à l'ouverture. En effet les contextes enregistrent les noms des brosses  utilisées et celles-ci doivent donc être retrouvées tel que chaque document les utilisent. 

 

Pour désactiver ce script si besoin, aller dans Fichier>Scripts>Evènements et désactiver la case "Activer les évènements". Pour effacer l'installation cliquer sur "tout supprimer" dans la même fenêtre, ou simplement relancer le script INSTALL.JSX.

 

Limitations: Actuellement, ce script impose certaines limitations:

- L'opacité de la brosse n'est pas sauvée car il n'est pas possible de la restaurer en script.  (Ni le flux).

- Les groupes de calques ne sont pas gèrés (ce qui est le plus gènant)

- Les outils prédéfinis ne sont pas gèrés (ce qui est gènant aussi)

- Un seul document doit être ouvert  à la fois

 

C'est une première version qui peut aider.

Une prochaine est en cours de dev qui utilisera les outils prédéfinis et les groupes.  

 

Merci de vos commentaires sur un article du blog.

 

 

/************************************************************************
   INSTALL.JSX

      Layer context Installer
 ************************************************************************
 To remove context infos:
 Menu : Fichier:Informations
 Page : Origine
 Member : instructions
 ************************************************************************
 18/12/2011 Habaki V1r02b: Activate events
 13/06/2010 Habaki V1r02 : Get file path with $
 09/05/2010 Habaki V1r01 : Creation
 ************************************************************************/
var ScriptName = "Layer Context Installer, Habaki 2011";

var ScriptFileName = "layerctx.jsx";
// Events to catch
var EventStNames = new Array("select", "open", "close", "set", "make",
                             "copyToLayer", "delete"
                             );
/*----------------------------------------------------------------------*/
var sTc  = function(v) { return(app.typeIDToCharID(app.stringIDToTypeID(v)));};
/*----------------------------------------------------------------------*
                        Main
 *----------------------------------------------------------------------*/
try{
  var notifs = notifiers;
  var Script;
  var str = "";
  var i, conf=0;
  var uninstall = 0;
 
  Script = new File($.fileName);
  Script = new File(Script.path + "/" + ScriptFileName);
 
  for(i=notifiers.length;i>0;i--) {
    if (notifs[i-1].eventFile.name != ScriptFileName) continue;
    if (conf==0 && confirm("Already INSTALLED !\nUNINSTALL ? (else Reinstall)",
        true,
        ScriptName)) {
      uninstall = 1;
    }
    conf = 1;
    notifs[i-1].remove();
  } //for
  if (uninstall) {
    throw(0);
  }
 
  for(i=0;i<EventStNames.length;i++) {
    try{
      notifs.add(sTc(EventStNames[i]), Script);
      str += " " + EventStNames[i];
    } catch(e) {}
  } //for
 
  if (str) {
    str = "New installed Events: "
        + str + "\n"
        + "On File: " + Script.fsName;
  } else {
    str = "All events already installed\n";
  }
  str = "INSTALLATION OK !\n" + str;
  alert(str, ScriptName);
  if (!notifiersEnabled && confirm("Activate Immediatly ? ",
      true,
      ScriptName)) {
    alert("To desactivate: Fichier>Scripts>Events>Activate to Off", ScriptName);
    notifiersEnabled = true;
  }
} catch(ex){
  if (ex) alert(ex.message, ScriptName);
}

/************************************************************************/

 

DEUXIEME PARTIE : LAYERCTX.JSX

 

/************************
 LAYERCTX.JSX
 ************************
 18/12/2011 Habaki V1r02b: Ignore Opacity
 30/05/2010 Habaki V1r02 : Replace some events
 09/05/2010 Habaki V1r01 : Creation
 ************************/
var ScriptName = "Layer context, (c) Habaki 2010-2011";
var Verbose  = 0; // 0:mute, 1: All msgs and ask for context creation
var Verbose2 = 0; // Just context (0:mute, 1:In, 2:Out)
var Verberr  = 1; // Errors (0:mute)
/************************
/*----------------------*
        Current
 *----------------------*/
var Layers;

var LayerCur = "";
var ToolCur  = "";
var BrushCur = "";
var BrushDiameterCur = 0.0;
var BrushOpacityCur = 100;
var ColorFGCur = "";
var ColorBGCur = "";

var BrushSelectOk = 0;
/*----------------------*
 Replace brushes
 *----------------------*/
function brush_ListReplace(FPath // .doc path
              )
{
  var FPath2;

  if (FPath == "") {
    FPath2 = String(activeDocument.fullName);
  } else FPath2 = String(FPath);
  FPath2 = FPath2.slice(0, FPath2.lastIndexOf(".")) + ".ABR";
  if (Verbose & 1) alert("Load:" + FPath2, "Brushes");
  if (!(new File(FPath2)).exists) {
    alert(FPath2  + " not Found !\nKeep current Brushes","Brushes");
    return;
  }
  var idsetd = charIDToTypeID( "setd" );
  var desc10 = new ActionDescriptor();
  var idnull = charIDToTypeID( "null" );
  var ref1 = new ActionReference();
  var idPrpr = charIDToTypeID( "Prpr" );
  var idBrsh = charIDToTypeID( "Brsh" );
  ref1.putProperty( idPrpr, idBrsh );
  var idcapp = charIDToTypeID( "capp" );
  var idOrdn = charIDToTypeID( "Ordn" );
  var idTrgt = charIDToTypeID( "Trgt" );
  ref1.putEnumerated( idcapp, idOrdn, idTrgt );
  desc10.putReference( idnull, ref1 );
  var idT = charIDToTypeID( "T   " );
  desc10.putPath( idT, new File( FPath2 ) );
  executeAction( idsetd, desc10, DialogModes.NO );
}
/*----------------------*
 Store brushes
 *----------------------*/
function brush_ListStore(FPath // doc file
            )
{
  var FPath2;
 
  if (FPath == "") {
    FPath2 = String(activeDocument.fullName);
  } else FPath2 = String(FPath);

  FPath2 = FPath2.slice(0, FPath2.lastIndexOf(".")) + ".ABR";
  if (Verbose & 1) alert("Stores:" + FPath2, "Brushes");
 
  var AD = new ActionDescriptor();
  AD.putPath( charIDToTypeID( "null" ), new File( FPath2) );
  var AR = new ActionReference();
  var idPrpr = charIDToTypeID( "Prpr" );
  var idBrsh = charIDToTypeID( "Brsh" );
  AR.putProperty( idPrpr, idBrsh );
  var idcapp = charIDToTypeID( "capp" );
  var idOrdn = charIDToTypeID( "Ordn" );
  var idTrgt = charIDToTypeID( "Trgt" );
  AR.putEnumerated( idcapp, idOrdn, idTrgt );
  AD.putReference( charIDToTypeID( "T   " ), AR );
  executeAction(charIDToTypeID( "setd" ), AD, DialogModes.NO );
}
/*----------------------*
 Layer Properties
 *----------------------*/
// New for current
function LayerPropNew() {
  return(activeDocument.activeLayer.name + ";;;;;;");
}
// Select
function LayerPropSelect(Prop)
{
  //if (Verbose) alert("PropSelect: " +Prop[0]+";"+Prop[1]+";"+Prop[2]+";"+Prop[3]+";"+Prop[4]+";"+Prop[5]+";", ScriptName);
 
  if (Prop[1]) ToolSelect(Prop[1]);
  if (Prop[2]) BrushSelect(Prop[2]);
  if (Prop[3]) ColorFGSelect(Prop[3]);
  if (Prop[4]) ColorBGSelect(Prop[4]);
  if (Prop[5]) BrushDiameterSelect(parseFloat(Prop[5]));
  if (Prop[6]) BrushOpacitySelect(parseFloat(Prop[6]));
}
// Selected
function LayerPropSelected(Prop)
{
  LayerCur = Prop[0];
  ToolCur = Prop[1];
  BrushCur = Prop[2];
  ColorFGCur = Prop[3];
  ColorBGCur = Prop[4];
  BrushDiameterCur = parseFloat(Prop[5]);
  BrushOpacityCur  = parseFloat(Prop[6]);
  if (LayerCur != activeDocument.activeLayer.name) {
    if (Verbose) alert("Wrong LayerCur:"  + LayerCur);
    LayerSelected("");
  }
}
// Build
function LayerProp(LName) // Layer name
{
  if (LName)
    return(LName + ";"
         + ToolCur + ";"
         + BrushCur + ";"
         + ColorFGCur + ";"
         + ColorBGCur + ";"
         + String(BrushDiameterCur) + ";"
         + String(BrushOpacityCur) + ";"
         );
  else
    return("");
}
//--------------------
function LayerIndex(Name)
{
  var i;
  var Prop;
 
  for (i=2; i < Layers.length;i++) {
    Prop = Layers[i].split(";");
    if (Prop[0]==Name) {
      return(i);
    }
  }
  return(0);
}
/*----------------------*
 Layer
 *----------------------*/
function LayerSelected(Name)
{
  var Prop;
  var Idx;
 
  if (Name == "") Name = activeDocument.activeLayer.name;
  if (Verbose) alert("Layer selected:" + Name, ScriptName);
 
  if (Name==LayerCur) Idx = 1; //ex: select document
  else
    Idx = LayerIndex(Name);
  if (Idx) {
    Prop = Layers[Idx].split(";");
    if (Idx > 1) Layers[Idx] = LayerProp(LayerCur);
    LayerPropSelect(Prop);
  } else{
    Layers[Layers.length] = LayerProp(LayerCur);
  }
  LayerCur = Name;
}
//--------------------
function LayerRenamed(Name) // Current
{
  if (Verbose) alert("Layer renamed: " + Name, ScriptName);
  LayerCur = Name;
}
//--------------------
function LayerDeleted() // Current
{
  // Keep the layer in the list in case of alt_ctrl_z
  if (Verbose) alert("Layer deleted: " + LayerCur, ScriptName);
  LayerSelected("");
}
/*----------------------*
        Colors
 *----------------------*/
function ColorFGSelect(Color)
{
  ColorFGCur = Color;
  if (Verbose) alert("Foreground Color: " + ColorFGCur, ScriptName);
  foregroundColor.rgb.hexValue = ColorFGCur;
}
//--------------------
function ColorFGGet()
{
  return(foregroundColor.rgb.hexValue);
}
//--------------------
function ColorBGSelect(Color)
{
  ColorBGCur = Color;
  if (Verbose) alert("Background Color: " + ColorBGCur, ScriptName);
  backgroundColor.rgb.hexValue = ColorBGCur;
}
//--------------------
function ColorBGGet()
{
  return(backgroundColor.rgb.hexValue);
}
/*----------------------*
        Tool
 *----------------------*/
function ToolSelected(Name)
{
  if (Name == "historyState") {
    LayerSelected("");
    return;
  }
  ToolCur = Name;
  if (Verbose) alert("Tool selected:" + Name, ScriptName);
 
  if (ToolCur =="paintbrushTool") {
    BrushSelect(BrushCur);
    BrushDiameterSelect(BrushDiameterCur);
    BrushOpacitySelect(BrushOpacityCur);
  }
}
//--------------------
function ToolSelect(Name)
{
  var AD = new ActionDescriptor();
  var AR = new ActionReference();
  if (Verbose) alert("Tool select:" + Name, ScriptName);
  AR.putClass(stringIDToTypeID(Name));
  AD.putReference(charIDToTypeID("null"), AR);
  executeAction(charIDToTypeID("slct"), AD, DialogModes.NO);
 
  ToolCur = Name;
 
}
/*----------------------*
 Paint Brush
 *----------------------*/
function BrushSelected(Name)
{
  if (ToolCur != "paintbrushTool") return;
  BrushCur = Name;
  if (Verbose) alert("Brush selected:" + Name, ScriptName);
  BrushDiameterCur = 0.0;
}
//--------------------
function BrushSelect(Name)
{
  var AD = new ActionDescriptor();
  var AR = new ActionReference();
 
  if (BrushSelectOk) return;
  if (!Name) return;
  if (Verbose) alert("Brush select:" + Name, ScriptName);
  try{
    AR.putName(charIDToTypeID("Brsh"), Name);
    AD.putReference(charIDToTypeID("null"), AR);
    executeAction(charIDToTypeID("slct"), AD, DialogModes.NO );
    BrushSelectOk = 1;
 
    BrushCur = Name;
  } catch(ex) {
    if (ex && Verberr) alert("UNKNOWN BRUSH: " + Name + "\n", ScriptName);
  }
}
//--------------------
function BrushDiameterSelected(Diam)
{
  if (ToolCur != "paintbrushTool") return;
  BrushDiameterCur = Diam;
  if (Verbose) alert("Brush Diameter selected:" + Diam, ScriptName);
}
//--------------------
function BrushDiameterSelect(/* float */ Diam)
{
  var AD = new ActionDescriptor();
  var AR = new ActionReference();
  var AD2 = new ActionDescriptor();
 
  if (Verbose) alert("Brush Diameter select:" + Diam, ScriptName);
  if (Diam && ToolCur == "paintbrushTool") {
    AR.putEnumerated(charIDToTypeID("Brsh"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
    AD.putReference(charIDToTypeID("null"), AR);
    AD2.putUnitDouble(stringIDToTypeID("masterDiameter"),
                      charIDToTypeID("#Pxl"), Diam);
    AD.putObject(charIDToTypeID("T   "), charIDToTypeID("Brsh"), AD2);
    executeAction(charIDToTypeID("setd"), AD, DialogModes.NO );
  }
  BrushDiameterCur = Diam;
}
/*-----------------------------------------------*
                        Brush Opacity
 *-----------------------------------------------*/
function BrushOpacityGet()
{
  if (ToolCur != "paintbrushTool") return(100);
  return(100);
  /* Useless : Select is not available
  var AR = new ActionReference();
  AR.putEnumerated(charIDToTypeID("capp"),
                    charIDToTypeID("Ordn"),
                    charIDToTypeID("Trgt")
                    );
  var AD = executeActionGet(AR);
  AD = AD.getObjectValue(stringIDToTypeID("currentToolOptions"));
  return(AD.getInteger(stringIDToTypeID("opacity")));
  */
}
//--------------------
function BrushOpacitySelected(Percent)
{
  if (ToolCur != "paintbrushTool") return;
  BrushOpacityCur = Percent;
  if (Verbose) alert("Brush Opacity selected:" + Percent, ScriptName);
}
//--------------------
function BrushOpacitySelect(/* float */ Percent)
{
  if (ToolCur != "paintbrushTool") return;
  if (BrushOpacityCur == BrushOpacityGet()) return;
  if (Verbose) alert("Brush Opacity select:" + Percent, ScriptName);
  // No script available
}
/*----------------------*
 Form
 *----------------------*/
function FormSelected(Class, Name)
{
  Class = typeIDToCharID(Class);
  /* Layer is selected with activeLayer
  if (Class == 'Lyr ') {
    LayerSelected(Name);
  }
  else
  */
  if (Class == 'Brsh') {
    ToolCur ="paintbrushTool";
    BrushSelected(Name);
  }
}
/*----------------------*
        Main
 *----------------------*/
try{
  var i, j, L, Prop;
  var St = "";
  var Ref, Class;
  var Key, KeySt, Type, Val;
  var Key1St ="";
  var TypeSt = "?";
  var ValSt = "?";
  var NoArgs=0;
 
  try{ arguments } catch(e) {NoArgs = 1;}
  if (NoArgs || arguments.length < 2) {
    alert("For Install/Uninstall execute Install.jsx", ScriptName);
    throw(0);
  }
 
  var AD        = arguments[0];
  var EventName = typeIDToStringID(arguments[1]);
  var AR, Form, Class, ClassSt;
  var Info;
 
  if (Verbose) alert("Event: " + EventName, ScriptName);
  // Load Context (WRNG: on close doc is no more here)
  if (EventName != "close") {
  
    if (documents.length==0) throw(0);
    Info = activeDocument.info;
    St = Info.instructions;  // Metadata
    if (St == undefined) St == "";
    if (Verbose2 & 1) alert("->Ctx(" + St + ")", ScriptName);
  
    // Load Layers
    Layers = St.split("\n");
    if (Layers[0] != "LCtx" || Layers[1] == "") {
      if (Layers[0] && Layers[0] != "LCtx" && Verbose==0) {
        throw(0);
      }
      if (!confirm("Create Contexts for the Layers of this document ?", true, ScriptName)) {
        Info.instructions = "LCtx=No\n";
        throw(0);
      }
      Layers = new Array();
      Layers[0] = "LCtx"; // Magic word
      Layers[1] = LayerPropNew();
      if (Verbose) alert("New Context", ScriptName);
    }
    Prop = Layers[1].split(";");
    LayerPropSelected(Prop); // Restore current
  }
  // Parse Event
  if (EventName == "select") {
  
    Key  = AD.getKey(0);
    KeySt= typeIDToStringID(Key);
    Type = AD.getType(Key);
    if (KeySt=="null") {
      if (Type == DescValueType.CLASSTYPE) {
        Type = AD.getClass(Key);
        ToolSelected(typeIDToStringID(Type));
      }
      else
      if (Type == DescValueType.REFERENCETYPE) {
        AR = AD.getReference(Key);
        Form = AR.getForm();
        Class = AR.getDesiredClass();
        ClassSt = typeIDToStringID(AR.getDesiredClass());
      
        if (ClassSt == "document") {
          LayerSelected("");
        }
        else
        if (Form == ReferenceFormType.NAME) {
          FormSelected(Class, AR.getName());
        }
        else
        if (Form == ReferenceFormType.CLASSTYPE) {
          ToolSelected(ClassSt);
        }
      }
    }
  }
  else
  if (EventName == "open") {

    Key  = AD.getKey(0);
    KeySt= typeIDToStringID(Key);
    Type = AD.getType(Key);
    if (KeySt=="null") {
      if (Type == DescValueType.ALIASTYPE) {
        // Open document
        brush_ListReplace(AD.getPath(Key));
        LayerSelected("");
      }
    }
  }
  else
  if (EventName == "close" && AD.count >=1) {
    // close document: only event arg is available

    try{
      Key  = AD.getKey(1);
      KeySt= typeIDToStringID(Key);
      Type = AD.getType(Key);
      if (KeySt == "in" && Type == DescValueType.ALIASTYPE) {
        brush_ListStore(AD.getPath(Key));
      }

    } catch(e) {}
  }
  else
  if (EventName == "set") {
    Key  = AD.getKey(0);
    KeySt= typeIDToStringID(Key);
    Type = AD.getType(Key);
    if (KeySt=="null") {
      if (Type == DescValueType.REFERENCETYPE) {
        AR = AD.getReference(Key);
        ClassSt = typeIDToStringID(AR.getDesiredClass());
        if (ClassSt == "brush" || ClassSt == "layer") {
          Key  = AD.getKey(1);
          KeySt= typeIDToStringID(Key);
          Type = AD.getType(Key);
          if (KeySt == "to") {
            if (Type == DescValueType.OBJECTTYPE) {
              Type = AD.getObjectType(Key);
              TypeSt = typeIDToStringID(Type);
              AD = AD.getObjectValue(Key);
              if (TypeSt == "brush" || TypeSt == "layer") {
                Key  = AD.getKey(0);
                Type = AD.getType(Key);
                if (typeIDToStringID(Key) == "masterDiameter") {
                  if (Type == DescValueType.UNITDOUBLE) {
                    // Type = AD.getUnitDoubleType(Key);
                    // typeIDToStringID(Type) == pixelUnit
                    BrushDiameterSelected(AD.getUnitDoubleValue(Key));
                  }
                }
                else
                if (typeIDToStringID(Key) == "name" && TypeSt == "layer") {
                  if (Type == DescValueType.STRINGTYPE) {
                    //Type = AD.getUnitDoubleType(Key);
                    // typeIDToStringID(Type) == pixelUnit
                    LayerRenamed(AD.getString(Key));
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  // Other Events that need to be catched
  // make, copyToLayer, delete
  //else throw(0);
 
  // Save Context
  if (EventName != "close") {
    ColorFGCur = ColorFGGet();
    ColorBGCur = ColorBGGet();
    BrushOpacityCur = BrushOpacityGet();
    St = "LCtx\n" + LayerProp(LayerCur) + "\n";
    for (i=2;i < Layers.length;i++)  {
      if (Layers[i]) St += Layers[i] + "\n";
    } // for
    // Save config
    if (Verbose2 & 2) alert("<-Ctx(" + St + ")", ScriptName);
    Info.instructions = St;
  }
 
} catch(ex) {
  if (ex && Verberr) alert(ex.message, ScriptName);
}

 

 

Partager cette page

Repost 0
Published by