Overblog
Suivre ce blog Administration + Créer mon blog
/ / /

Ce script automatise la création de panoramas.

On suppose qu'il existe un répertoire principal contenant des sous-répertoires qui chacun contient des images pouvant être fusionnées en un panorama.

Le script traite successivement chaque sous-répertoire et produit une image JPG du panorama correspondant. L'image a le même nom que le sous-répertoire et est crée dans le répertoire principal.

Au lancement du script, le nom complet du répertoire principal est demandé.  

Le script est constitué de deux fichiers  qui doivent être copiés dans le même répertoire (celui qu'on veut).

PHMSCAN.JSX

PHMERGE.JSX

Pour l'exécuter dans Photoshop, désigner PHMSCAN.JSX avec le menu Fichier/Scripts/Parcourir.

INFORMATION:

Le script PHMSCAN utilise des scripts fournis en standard par Adobe avec Photoshop dans PHMERGE pour remplacer la fonction  makePhotomerge() qui ne fonctionne pas avec CS4.

   

PHMERGE est une version de l'un de ces scripts Adobe que j'ai du modifier pour corriger un bug.

Panorama réalisé avec les 3 images suivantes
Panorama réalisé avec les 3 images suivantesPanorama réalisé avec les 3 images suivantesPanorama réalisé avec les 3 images suivantes

Panorama réalisé avec les 3 images suivantes

Partager cet article
Repost0
Published by Habaki - dans Scripts
/ / /

 

Ce script permet de ranger les images JPG d'un répertoire en mosaique. Le résultat est sauvé dans une image JPG.

La mosaique est constituée d'une grille dont chaque maille à la même taille. Les images sont mises à l'échelle et sont placées au centre de chaque maille en gardant leurs proportions.

Si les images ont toutes la même taille, elles rempliront exactement chaque maille.

Les mailles peuvent être séparées par un espace paramètrable (Gap) et la mosaique entourée d'une marge jusqu'au bord du document (Margin).  

 

Il est possible de configurer la mosaique en modifiant directement dans le script les valeurs qui se trouvent dans la section "Parametres".

Principalement il faut :

D'abord choisir la taille du document final en pixels (DocH, DocV).

Ensuite le nombre d'images par ligne et par colonne (ImgNbH, ImgNbV).

Puis les marges minimum autour du document (MarginH, MarginV).

Enfin les espaces entre mailles (GapH, GapV).

 

Pour ceux qui ne connaissent pas du tout la programmation, ces valeurs sont écrites entre le signe = et le point-virgule suivant. Le texte après // et jusqu'à la fin de la ligne ne fait pas partie du programme du script. C'est un commentaire et on peut y écrire ce que l'on veut: généralement une explication, ou une ligne de programme que l'on veut retirer du script mais sans l'effacer.

Par exemple pour que les images soient collées les unes autres, il faut modifier les deux lignes suivantes:

var GapH        = 10;   // Separation horizontale entre images (pixels)
var GapV        = 10;   // Separation verticale   entre images (pixels) 

en

var GapH        = 0;   // Separation horizontale entre images (pixels)
var GapV        = 0;   // Separation verticale   entre images (pixels)

 

Attention cependant. les images seront collées si elles ont toutes la même taille. Sinon elles seront insèrées dans des mailles qui elles seront collées ensemble.

 

La couleur de fond de la mosaique est ici la couleur d'arrière plan dans Photoshop. Mais si l'on remplace

var DocColor = DocumentFill.BACKGROUNDCOLOR;

par

var DocColor = DocumentFill.WHITE;

on aura toujours du blanc.

 

La valeur de la configuration CfgMode permet différents modes qui peuvent s'additionner. Ils sont notés 1,2 et 4 et justement on additionne les valeurs des modes que l'on veut. Par exemple pour centrer les images et garder les calques dans photoshop sans les fusionner on donne la valeur 4 + 1 . Donc on écrit :

var CfgMode = 4 + 1;

 

Pour exécuter ce script, récupèrer le fichier MOSA04.JSX  (mosaique version 4) puis désigner ce fichier par le menu Fichier>Scripts>Parcourir.

 

Ci-dessous une image d'exemple réalisée avec le script:

 

mosaique Tintin2

 

Partager cet article
Repost0
Published by Habaki - dans Scripts
/ / /

Ce script pemret de visualiser tous les évènements survenant dans l'utilisation de photoshop , comme ouvrir ou fermer un document, changer d'outil , etc...

Pour l'activer il suffit de le lancer "Fichier/Scripts/Parcourir".

Pour le désactiver,aler dans "Fichier/Scripts/Gestionnaire d'Evenements" et décocher la case "Activer...".  

 

/****************************************************
  EVENT VIEWER
 ****************************************************
 Just execute the script to install it for wanted events.
 BEWARE of PRINT : Bug in event manager
 ****************************************************
 30/05/2010 Habaki V1r02 : Add auto install
 02/05/2010 Habaki V1r01 : Creation
 ****************************************************/
var ScriptName = "Event Viewer, (c) Habaki 2010";
var Verbose = 1;

// Events to catch
//var EventStNames = new Array("select", "open");
var EventStNames = new Array("all");
var EventCharNames = new Array('ntfy');

var ScriptFilePath = $.fileName;

var sTc = function(v) { return(app.typeIDToCharID(app.stringIDToTypeID(v)));};
/*--------------------------------------------------*
 Num to String (enumeration value)
 *--------------------------------------------------*/
function NumSt(Num)
{
  var St = app.typeIDToStringID(Num);
  if (St) return("\"" + St + "\"");
  St = app.typeIDToCharID(Num);
  if (St) return("'" + St + "'");
  return(String(Num));
}
/*--------------------------------------------------*
 ID to String
 *--------------------------------------------------*/
function IDSt(ID)
{
  var St = app.typeIDToStringID(ID);
  if (St) return("\"" + St + "\"");
  return("'" + app.typeIDToCharID(ID) + "'");
}
/*--------------------------------------------------*
 Print Action Reference to string
 *--------------------------------------------------*/
function AR_PrintSt(AR, Margin)
{
  var St = Margin;
  var Form;
  var ValSt, FormSt, ValClass, ValClassc;
 
  AR.getName();
  Form = AR.getForm();
  ValClass = app.typeIDToStringID(AR.getDesiredClass());
  ValClassc = app.typeIDToCharID(AR.getDesiredClass());
 
  if (Form == ReferenceFormType.CLASSTYPE) {
    FormSt = "Class";
    ValSt = ValClass;
  }
  else
  if (Form == ReferenceFormType.ENUMERATED) {
    FormSt = "Enumerated";
    Type = AR.getEnumeratedType();
    Val  = AR.getEnumeratedValue();
    ValSt = "(Type=" + IDSt(Type)
          + ", Val=" + NumSt(Val)
          + ")";
  }
  else
  if (Form == ReferenceFormType.IDENTIFIER) {
    FormSt = "Identifier";
    ValSt  = IDSt(AR.getIdentifier());
  }
  else
  if (Form == ReferenceFormType.INDEX) {
    FormSt = "Index";
    ValSt  = String(AR.getIndex());
  }
  else
  if (Form == ReferenceFormType.NAME) {
    FormSt = "Name";
    ValSt = "\"" + AR.getName() + "\"";
  }
  else
  if (Form == ReferenceFormType.OFFSET) {
    FormSt = "Offset";
    ValSt = String(AR.getOffset());
  }
  else
  if (Form == ReferenceFormType.PROPERTY) {
    FormSt = "Property";
    ValSt = IDSt(AR.getProperty());
  }
  else {
    FormSt = "??";
    ValSt = "??";
  }
 
  St += "Class=" + ValClass
     //+ "('" + ValClassc + "')" // CharID
     + ", " + FormSt + "=" + ValSt
     ;
  return(St);
}
/*--------------------------------------------------*
 Print Descriptor to string
 *--------------------------------------------------*/
function DS_PrintSt(DS, Key, Margin)
{
  var Val;
  var TypeSt = "?";
  var ValSt = "?";
  var Type = DS.getType(Key);
 
  if (Type == DescValueType.ALIASTYPE) {
    TypeSt = "Path";
    ValSt = DS.getPath(Key);
  }
  else
  if (Type == DescValueType.BOOLEANTYPE) {
    TypeSt = "Boolean";
    ValSt = DS.getBoolean(Key);
  }
  else
  if (Type == DescValueType.CLASSTYPE) {
    TypeSt = "Class";
    Type = DS.getClass(Key);
    ValSt = IDSt(Type);
  }
  else
  if (Type == DescValueType.DOUBLETYPE) {
    TypeSt = "Double";
    ValSt = String(DS.getDouble(Key));
  }
  else
  if (Type == DescValueType.ENUMERATEDTYPE) {
    TypeSt = "Enumerated";
    Type = DS.getEnumerationType(Key);
    Val  = DS.getEnumerationValue(Key);
    ValSt = "Type=" + IDSt(Type)
          + ", Val=" + NumSt(Val)
          ;
  }
  else
  if (Type == DescValueType.INTEGERTYPE) {
    TypeSt = "Integer";
    ValSt = String(DS.getInteger(Key));
  }
  else
  if (Type == DescValueType.LISTTYPE) {
    TypeSt = "List";
    Val = DS.getList(Key);
    ValSt = "\r"
          + AL_PrintSt(Val, Margin + "    ")
          ;
  }
  else
  if (Type == DescValueType.OBJECTTYPE) {
    TypeSt = "Object";
    Type = DS.getObjectType(Key);
    Val = DS.getObjectValue(Key);
    ValSt = "Type=" + IDSt(Type) + ",\r"
          + AD_PrintSt(Val, Margin + "    ")
          ;
  }
  else
  if (Type == DescValueType.RAWTYPE) {
    TypeSt = "Raw";
    ValSt = DS.getData(Key);
    //ValSt = "Len="+ ValSt.length + ", Data={" + DS.getData(Key) + "}";
    ValSt = "Len="+ ValSt.length + ", Data={" + "..." + "}";
  }
  else
  if (Type == DescValueType.REFERENCETYPE) {
    TypeSt = "Reference";
    Val = DS.getReference(Key);
    ValSt = AR_PrintSt(Val, "");
  }
  else
  if (Type == DescValueType.STRINGTYPE) {
    TypeSt = "String";
    ValSt = "\"" + DS.getString(Key) + "\"";
  }
  else
  if (Type == DescValueType.UNITDOUBLE) {
    TypeSt = "UnitDouble";
    Type = DS.getUnitDoubleType(Key);
    ValSt = "Type=" + IDSt(Type)
          + ", Val=" + String(DS.getUnitDoubleValue(Key))
          ;
  }
  else {
    TypeSt = "Type";
    ValSt = DS.getType(Key);
  }
  return(TypeSt + "(" + ValSt + ")");
}
/*--------------------------------------------------*
 Print Action List to string
 *--------------------------------------------------*/
function AL_PrintSt(AL, Margin)
{
  var Key;
  var St = "";
 
  for (Key=0;Key < AL.count; Key++) {
    St += Margin + "[" + String(Key) + "]:"
        + DS_PrintSt(AL, Key, Margin)
        ;
    if (Key == AL.count-1) St += "\r";
    else                   St += ",\r"
  } // for
  St += Margin;
  return(St);
}
/*--------------------------------------------------*
 Print Action Descriptor to string
 *--------------------------------------------------*/
function AD_PrintSt(AD, Margin)
{
  var i;
  var St = "";
  var Key;
 
  for (i=0;i < AD.count; i++) {
    Key  = AD.getKey(i);
    St += Margin + "Key[" + String(i) + "]:" + IDSt(Key)
       + " = "
       + DS_PrintSt(AD, Key, Margin)
       ;
    if (i == AD.count-1) St += "\r";
    else                 St += ",\r"
  } // for
  St += Margin;
  return(St);
}
/*--------------------------------------------------*
   Parse an event
 arguments[0] : ActionDescriptor
 arguments[1] : Event typeID
 arguments[2..] : ?
 *--------------------------------------------------*/
try {
  if (arguments.length < 2) {
    //alert("arguments.length=" + arguments.length, ScriptName);
    alert("INSTALLATION", ScriptName);
    try{
      app.notifiers.removeAll;
      for (i=0;i < EventStNames.length; i++) {
        app.notifiers.add(sTc(EventStNames[i]), new File(ScriptFilePath));
      }
      for (i=0;i < EventCharNames.length; i++) {
        app.notifiers.add(EventCharNames[i], new File(ScriptFilePath));
      }
      app.notifiersEnabled = true;
    } catch (e) {}
    throw(0);
  }
 
  var AD        = arguments[0];
  var EventName = app.typeIDToStringID(arguments[1]);
  var St;
 
  St = EventName + " \r";
  St += AD_PrintSt(AD, "");
  // Other args
  for (i=2;i < arguments.length; i++){
    St += "Arg[" + String(i) + "]=" + String(arguments[i]);
  }
 
  if (Verbose) alert(St, ScriptName);
 
} catch(ex) {
  if (ex) alert(ex.message, ScriptName)
}
/*--------------------------------------------------*/

Partager cet article
Repost0
Published by Habaki - dans Scripts
/ / /

Ce script permet d'imprimer un document par morceaux à l'échelle 1, quand l'image est trop grande pour l'imprimante, tout en minimisant la surface de papier utilisé. Selon la forme de l'image et l'imprimante, les morceaux sont découpés dans le  mode optimal : portrait ou paysage.  

Les paramètres de l'imprimante doivent être définis dans la section PARAMETRES, surtout les marges non imprimées  aux bords du papier.

Dans cette version, l'imprimante doit être configurée en mode portrait (les morceaux en paysage sont tournés automatiquement).

 

Il est possible également de signaler des marges déjà existantes autour de l'image, ce qui permet de ne pas les imprimer et de gagner éventuellement beaucoup de papier. Par exemple une planche de BD en A3 peut ainsi être imprimée en deux feuilles A4, ce qui ne serait pas possible si la totalité du A3 devait être imprimé. En effet, à cause des marges de l'imprimante il faudrait 4 feuilles.

 

Enfin l'image peut être imprimée avec un cadre pour faciliter ensuite le découpage du papier si besoin.  

 

C'est évidemment un outil essentiel pour  imprimer une planche mise en place avec Photoshop afin de la décalquer  ensuite sur du bon papier à la table lumineuse, ou simplement pour imprimer un poster.

  

msnp005 72A3 

Voici par exemple une planche A3 dont les marges droite et gauche peuvent être ignorées sur 8mm  lors de l'impression. Ces marges peuvent être paramétrées dans le script.

 

 

 

 

 

 

 

 

 

 

 

L'image ci-dessous, obtenue automatiquement par le script, montre un découpage (par les lignes grises) en seulement  trois feuilles A4 portrait. Si les marges hautes et basses avaient pu être ignorées aussi (ce n'est pas le cas à cause du titre et de la signature) l'impression aurait utilisé deux feuilles seulement!

 

  Note: Les marges de l'imprimante sont en dehors du cadre gris.

 

 msnp005 print72b

Si ce script vous intéresse dans une version plus conviviale, c'est-à-dire avec une interface utilisateur qui permette de règler facilement les paramètres sans modifier le script, laisssez un message sur le blog.

 

 Copier le script qui suit jusqu'à la fin du texte dans un fichier .JSX. L'exécuter par le menu  Fichier:Scripts:Parcourir. 

/************************************************************************
                IMPRESSION D'UNE IMAGE PAR MORCEAUX
 ************************************************************************
 Le but est d'imprimer l'image a l'echelle 1 sur un minimum de papier.
 L'imprimante doit etre configuree selon la section "Parametres".
 Inscrire dans les variables PrintMargX les valeurs minimum des marges
 (ou plus) imposees par l'imprimante, sinon le document sera tronque.
 ************************************************************************
 19/06/2012 Habaki V1r01b: Marges d'image et impression d'un cadre
 14/06/2012 Habaki V1r01 : Creation
 ************************************************************************/
var ModName   = "Impression";
var jpegOptions  = new JPEGSaveOptions();
var RulerUnits  = preferences.rulerUnits;
preferences.rulerUnits = Units.PIXELS;
var BGColor  = backgroundColor.rgb.hexValue;
/*----------------------------------------------------------------------*
   PARAMETRES
 Par defaut: Format A4 portrait.
 *----------------------------------------------------------------------*/
// PARAMETRES IMPRIMANTE
// Papier imprimante (portrait)
var SheetH = 29.7;  // Hauteur de papier (cm)
var SheetW = 21.0;  // Largeur de papier (cm)

// Marges minimum de l'imprimante
/*
var PrintMargL = 0;  // Marge gauche (cm)
var PrintMargR = 0;  // Marge droite (cm)
var PrintMargT = 0;  // Marge haute (cm)
var PrintMargB = 0;  // Marge basse (cm)
*/
var PrintMargL = 0.6;  // Marge gauche (cm)
var PrintMargR = 0.68;  // Marge droite (cm)
var PrintMargT = 0.6;  // Marge haute (cm)
var PrintMargB = 0.6;  // Marge basse (cm)

// PARAMETRES D'IMAGE
// Marges deja autour de l'image
// que l'on peut ne pas imprimer.
var ImgMargL = 0;  // Marge gauche (cm)
var ImgMargR = 0;  // Marge droite (cm)
var ImgMargT = 0;  // Marge haute (cm)
var ImgMargB = 0;  // Marge basse (cm)
/*
var ImgMargL = 0.8;  // Marge gauche (cm)
var ImgMargR = 0.8;  // Marge droite (cm)
var ImgMargT = 0.0;  // Marge haute (cm)
var ImgMargB = 0.5;  // Marge basse (cm)
*/
// Modes
var ImgModeFrame = true; // Imprimer un cadre autour de l'image
/*----------------------------------------------------------------------*/
// PARAMETRES DIVERS

// Rognage max de l'image pour economie de papier
var CropMax = 1.0;  // %

// Couleur de fond (si pas transparent): blanc
backgroundColor.rgb.hexValue = 'FFFFFF';
/*----------------------------------------------------------------------*
   Globals
 *----------------------------------------------------------------------*/
var DocMain;  // Document principal
var HistBack = 0; // Nb of History back to do
/************************************************************************
   HISTORY
 ************************************************************************/
function history_Back() {
  var idnull = charIDToTypeID( "null" );
  var idslct = charIDToTypeID( "slct" );
  var idHstS = charIDToTypeID( "HstS" );
  var idOrdn = charIDToTypeID( "Ordn" );
  var idPrvs = charIDToTypeID( "Prvs" );
  var AD = new ActionDescriptor();
  var AR = new ActionReference();
  AR.putEnumerated( idHstS, idOrdn, idPrvs );
  AD.putReference( idnull, AR );
  executeAction( idslct, AD, DialogModes.NO );
};
/************************************************************************
                        DRAW
 ************************************************************************/
function PathFillWhite()
{
  // WARNING: Si path vide => erreur : "Abandon par utilisateur"
  var idnull  = charIDToTypeID( "null" );
  var idFl    = charIDToTypeID( "Fl  " );
  var idPath  = charIDToTypeID( "Path" );
  var idOrdn  = charIDToTypeID( "Ordn" );
  var idTrgt  = charIDToTypeID( "Trgt" );
  var idWhPt  = charIDToTypeID( "WhPt" );
  var idUsng  = charIDToTypeID( "Usng" );
  var idFlCn  = charIDToTypeID( "FlCn" );
  var idWht   = charIDToTypeID( "Wht " );
  var idOpct  = charIDToTypeID( "Opct" );
  var idPrc   = charIDToTypeID( "#Prc" );
  var idMd    = charIDToTypeID( "Md  " );
  var idBlnM  = charIDToTypeID( "BlnM" );
  var idNrml  = charIDToTypeID( "Nrml" );
  var idRds   = charIDToTypeID( "Rds " );
  var idPxl   = charIDToTypeID( "#Pxl" );
  var idAntA  = charIDToTypeID( "AntA" );
 
  var AC = new ActionDescriptor();
  var AR = new ActionReference();
  AR.putEnumerated( idPath, idOrdn, idTrgt );
  AC.putReference( idnull, AR );
  AC.putBoolean( idWhPt, true );
  AC.putEnumerated( idUsng, idFlCn, idWht );
  AC.putUnitDouble( idOpct, idPrc, 100.000000 );
  AC.putEnumerated( idMd, idBlnM, idNrml );
  AC.putUnitDouble( idRds, idPxl, 1.000000 );
  AC.putBoolean( idAntA, true );
  executeAction( idFl, AC, DialogModes.NO );
  HistBack++;
}
/*----------------------------------------------------------------------*
                        Draw Rect
 *----------------------------------------------------------------------*/
function RectDrawWhite(doc, Resol, x, y, w, h, ep)
{
  var line = new Array(new PathPointInfo,new PathPointInfo,
                       new PathPointInfo,new PathPointInfo);
  var line2= new Array(new PathPointInfo,new PathPointInfo,
                       new PathPointInfo,new PathPointInfo);
  var subPath = new Array(new SubPathInfo, new SubPathInfo);
  var path;
 
  // Convert
  var r  = Resol /72.0;
  x = Math.round(x/r);
  y = Math.round(y/r);
  h = Math.round(h/r);
  w = Math.round(w/r);
  ep= Math.round(ep/r);
  // WARNING: Si path vide => erreur : "Abandon par utilisateur"
  if (ep < 1) ep = 1;
 
  line[0].kind   = PointKind.CORNERPOINT;
  line[0].anchor  = new Array(x, y);
  line[0].leftDirection  = line[0].anchor;
  line[0].rightDirection = line[0].anchor;
 
  line[1].kind   = PointKind.CORNERPOINT;
  line[1].anchor  = new Array(x+w, y);
  line[1].leftDirection  = line[1].anchor;
  line[1].rightDirection = line[1].anchor;
 
  line[2].kind   = PointKind.CORNERPOINT;
  line[2].anchor  = new Array(x+w, y+h);
  line[2].leftDirection  = line[2].anchor;
  line[2].rightDirection = line[2].anchor;
 
  line[3].kind   = PointKind.CORNERPOINT;
  line[3].anchor  = new Array(x, y+h);
  line[3].leftDirection  = line[3].anchor;
  line[3].rightDirection = line[3].anchor;
 
  subPath[0].operation = ShapeOperation.SHAPEADD;
  subPath[0].closed = true;
  subPath[0].entireSubPath = line;
 
  line2[0].kind   = PointKind.CORNERPOINT;
  line2[0].anchor  = new Array(x+ep, y+ep);
  line2[0].leftDirection = line2[0].anchor;
  line2[0].rightDirection = line2[0].anchor;
 
  line2[1].kind   = PointKind.CORNERPOINT;
  line2[1].anchor  = new Array(x+w-ep, y+ep);
  line2[1].leftDirection = line2[1].anchor;
  line2[1].rightDirection = line2[1].anchor;
 
  line2[2].kind   = PointKind.CORNERPOINT;
  line2[2].anchor  = new Array(x+w-ep, y+h-ep);
  line2[2].leftDirection = line2[2].anchor;
  line2[2].rightDirection = line2[2].anchor;
 
  line2[3].kind   = PointKind.CORNERPOINT;
  line2[3].anchor  = new Array(x+ep, y+h-ep);
  line2[3].leftDirection = line2[3].anchor;
  line2[3].rightDirection = line2[3].anchor;
 
  subPath[1].operation = ShapeOperation.SHAPESUBTRACT;
  subPath[1].closed = true;
  subPath[1].entireSubPath = line2;
 
  path = doc.pathItems.add("RectWhite", subPath);
  HistBack+=2;
  PathFillWhite();
  path.remove();
  HistBack++;
 
  return(0);
}
/************************************************************************
   Main
 ************************************************************************/
try{
 
  var H,W, HV, WV, HH, WH;
  var CropArea = new Array(); // L,T,R,B
  var Resol, CmToPx;
  var SH, SW;   // Sheet format (px)
  var PH, PW;   // Printed area inside a sheet (px)
  var ML,MT,MB,MR;  // Printer Margins (px)
  var IL,IT,IB,IR;  // Image Margins (px)
  var RH, RW;
  var CL,CT,CW,CH;  // Crop area
  var PN;   // Piece number
  var RCWH, RCHH, RCWV, RCHV;
  var RCW, RCH;   // Total printed area without margins
  var SurfV, SurfH;  // Surfaces
  var LD,LC;   // Layers
  var NFirstL;   // not first layer
  var Ep;
 
  DocMain = activeDocument;
  if (DocMain.activeLayer != DocMain.layers[0]) NFirstL = true;
  else              NFirstL = false;
 
  H = Math.floor(DocMain.height);
  W = Math.floor(DocMain.width);
  Resol = DocMain.resolution;
  CmToPx = Resol / 2.54;
 
  // Print format
  SH = Math.floor(SheetH * CmToPx);
  SW = Math.floor(SheetW * CmToPx);
  ML = Math.floor(PrintMargL * CmToPx);
  MT = Math.floor(PrintMargT * CmToPx);
  MB = Math.floor(PrintMargB * CmToPx);
  MR = Math.floor(PrintMargR * CmToPx);
 
  IL = Math.floor(ImgMargL * CmToPx);
  IT = Math.floor(ImgMargT * CmToPx);
  IB = Math.floor(ImgMargB * CmToPx);
  IR = Math.floor(ImgMargR * CmToPx);
 
  if (IL+IR >= W || IT+IB >= H){
    alert("ERREUR: Marges d'image trop grandes !",ModName);
  }
  // Remove document margins
  if (IB || IR) {
    DocMain.resizeCanvas(W-IR, H-IB,
                         AnchorPosition.TOPLEFT);
    HistBack++;
    W -= IR;
    H -= IB;
  }
  if (IL || IT) {
    DocMain.resizeCanvas(W-IL, H-IT,
                         AnchorPosition.BOTTOMRIGHT);
    HistBack++;
    W -= IL;
    H -= IT;
  }
 
  // Printed area on one sheet
  PW = SW-ML-MR;
  PH = SH-MT-MB;
  //alert("Doc:H="+H+",W="+W+",Area:PH="+PH+",PW="+PW+",Resol="+Resol);
 
  // Choix Portrait(Vertical)/Paysage(Horizontal)
  // Surface en decoupage mode portrait
  HV = H;
  WV = W;
  RCWV = (Math.floor(WV/PW)+(WV % PW ? 1: 0))*PW;
  if ((WV % PW) && (WV % PW) <= WV*CropMax/100) {
    if (confirm("ATTENTION: En Portrait, seulement "+(WV % PW)+" Px de trop en Largeur.\nCouper pour economie de papier ?",
                false, ModName)) {
      RCWV = Math.floor(WV/PW)*PW;
      WV = RCWV;
    }
  }
  RCHV = (Math.floor(HV/PH)+(HV % PH ? 1: 0))*PH;
  if ((HV % PH) && (HV % PH) <= HV*CropMax/100) {
    if (confirm("ATTENTION: En portrait, seulement "+(HV % PH)+" Px de trop en Hauteur.\nCouper pour economie de papier ?",
                false, ModName)) {
      RCHV = Math.floor(HV/PH)*PH;
      HV = RCHV;
    }
  }
  SurfV = (RCHV + MT + MB) *
          (RCWV + ML + MR);
 
  // Surface en decoupage mode paysage
  // Doc is rotated -90dg
  WH = H;
  HH = W;
  RCHH = (Math.floor(HH/PH)+(HH % PH ? 1: 0))*PH;
  if ((HH % PH) && (HH % PH) <= HH*CropMax/100) {
    if (confirm("ATTENTION: En Paysage seulement "+(HH % PH)+" Px de trop en Largeur.\nCouper pour economie de papier ?",
                false, ModName)) {
      RCHH = Math.floor(HH/PH)*PH;
      HH = RCHH;
    }
  }
  RCWH = (Math.floor(WH/PW)+(WH % PW ? 1: 0))*PW;
  if ((WH % PW) && (WH % PW) <= WH*CropMax/100) {
    if (confirm("ATTENTION: En Paysage seulement "+(WH % PW)+" Px de trop en Hauteur.\nCouper pour economie de papier ?",
                false, ModName)) {
      RCWH = Math.floor(WH/PW)*PW;
      WH = RCWH;
    }
  }
  SurfH = (RCHH + MT + MB) *
          (RCWH + ML + MR);
 
  if (SurfV <= SurfH) {
    //alert("Decoupage optimal Portrait");
    RCW = RCWV;
    RCH = RCHV;
    // Ici ajuster Ix
    H   = HV;
    W   = WV;
  } else {
    //alert("Decoupage optimal Paysage");
    DocMain.rotateCanvas(-90);
    HistBack++;
    RCW = RCWH;
    RCH = RCHH;
    // Ici ajuster Ix
    // + rotation Ix
    H = IL; IL = IT; IT = IR; IR = IB; IB = H;
    H   = HH;
    W   = WH;
  }
  // Centrage
  DocMain.resizeCanvas((W + RCW)/2 + MR,
                       (H + RCH)/2 + MB,
                       AnchorPosition.TOPLEFT);
  HistBack++;
  DocMain.resizeCanvas(RCW + MR + ML,
                       RCH + MB + MT,
                       AnchorPosition.BOTTOMRIGHT);
  HistBack++;
 
  if (ImgModeFrame) {
    // Cadre autour de l'image originale
    LC = DocMain.artLayers.add();
    LC.name = "Cadre";
    LC.blendMode = BlendMode.DIFFERENCE;
    HistBack += 3;
    Ep = Math.floor((H > W ? H : W)/1000);
    if (Ep < 1) Ep = 1;
    RectDrawWhite(DocMain,Resol,ML-IL-Ep+((RCW-W)/2),
                                MT-IT-Ep+((RCH-H)/2),
                                W+IL+IR+Ep,H+IT+IB+Ep,Ep);
  }
  // Draw layer de decoupage
  LD = DocMain.artLayers.add();
  LD.name = "Zones d'impression";
  LD.blendMode = BlendMode.DIFFERENCE;
  HistBack += 3;
  Ep = Math.floor((H > W ? H : W)/1000);
  if (Ep < 2) Ep = 2;
  CL = 0; 
  CT = 0;
  CW = SW;
  CH = SH;
  while(CT < H) {
    while(CL < W) {
      RectDrawWhite(DocMain,Resol, CL+ML,CT+MT,PW,PH,Ep);
      CL += PW;
    } // while
    CT += PH;
    CL  = 0;
  } // while
 
  if (confirm("Imprimer ce Decoupage ?\n(Sinon modifier la taille de l'image)",
              false, ModName)) {
    LD.visible = false;
    PN = 0;
    CL = 0;  CT = 0;
    CW = SW; CH = SH;
    while(CT < H) {
      while(CL < W) {
        PN++;
        CropArea[0] = CL;
        CropArea[1] = CT;
        CropArea[2] = CL+CW;
        CropArea[3] = CT+CH;
        DocMain.crop(CropArea);
        DocMain.print();
        history_Back();
        CL += PW;
      } // while
      CT += PH;
      CL  = 0;
    } // while
  }
} catch(ex) {
  alert(ex.message, ModName);
  /*
  if (confirm("ERREUR: "+ ex.message +
              "\n Stop for debug ?", false, ModName)) {
    HistBack = 0;
    NFirstL  = false;
  }
  */
}
for (;HistBack;HistBack--) history_Back();
if (NFirstL) history_Back();  // Dont ask why!!!

preferences.rulerUnits = RulerUnits;
backgroundColor.rgb.hexValue = BGColor;

Partager cet article
Repost0
Published by Habaki - dans Scripts
/ / /

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 cet article
Repost0
- dans Scripts
/ / /

Ce script permet de tracer un cadre autour d'une image (Avec Photoshop).

Le cadre est formé de 1 à 3 entourages dont on peut choisir l'épaisseur et la couleur. Les dimensions de l'image initiale ne sont pas modifées, mais l'ensemble est  agandi par le cadre.  

Il est possible également d'ajouter un texte dans l'un des coins.

En appliquant le script 2 ou 3 fois de suite ont peut obtenir des cadres plus complexes.

 Le script est doté d'une interface utilisateur très pratique. 

Dans l'exemple ci-dessous, le script a été appliqué deux fois pour obtenir 6 entourages (bleu blanc orange orange bleu noir : 2 entourages oranges se confondent), la 1ère fois avec un titre en bas à droite.  

 

cadre01a

    ---- donne ---->    cadre01b

 

Ce script est paramétré par  une interface utilisateur conviviale, et les paramètres peuvent être enregistrés.

Le script est multi-langues : Français, Allemand, Anglais.

Merci à Eddy pour sa traduction des messages en Allemand. 

 

Screenshot acores004

 

Le script est disponible dans le fichier joint : HABAKI_CADRE.JSX

L'exécuter par le menu  Fichier>Scripts>Parcourir. 

Cadres autour d'une image

Partager cet article
Repost0
Published by Habaki - dans Scripts
/ / /

 

A la base ce script visualise les points des tracés (pathItems) du document courant.

 

La sélection courante, pour être visualisée, est d'abord transformée en tracé (path) par la fonction SelToPath(1.0), donc avec une tolérance de 1 pixel. Elle sera affichée avec les tracés déjà définis.

 

Pour visualiser les tracés existants, sans la sélection courante, il suffit de mettre cette ligne

// SelToPath(1.0) ;

en commentaire dans le Main.

 

Ce script peut aussi servir d'exemple à une programmation concernant les tracés.

 

/************************************************************************
     Selection/Path Viewer
 ************************************************************************
 25/03/2012 Habaki V1r01b: Display path operation

 20/06/2010 Habaki V1r01 : Creation
 ************************************************************************/
var ScriptName= "Selection/Path Viewer, V1R01b Habaki";

/*----------------------------------------------------------------------*
   Convert selection into Path
 *----------------------------------------------------------------------*/
function SelToPath(
        tolerance  // Tolerance in pixels
        ) {
  var idMk = charIDToTypeID( "Mk  " );
  var AD = new ActionDescriptor();
  var idnull = charIDToTypeID( "null" );
  var AR1 = new ActionReference();
  var idPath = charIDToTypeID( "Path" );
  AR1.putClass( idPath );
  AD.putReference( idnull, AR1 );
  var idFrom = charIDToTypeID( "From" );
  var AR2 = new ActionReference();
  var idcsel = charIDToTypeID( "csel" );
  var idfsel = charIDToTypeID( "fsel" );
  AR2.putProperty( idcsel, idfsel );
  AD.putReference( idFrom, AR2 );
  var idTlrn = charIDToTypeID( "Tlrn" );
  var idPxl = charIDToTypeID( "#Pxl" );
  AD.putUnitDouble( idTlrn, idPxl, tolerance );
  executeAction( idMk, AD, DialogModes.NO );
}
/*----------------------------------------------------------------------*
   Main
 *----------------------------------------------------------------------*/
try {
  var Paths, Path;
  var SubPaths, Item;
  var Points, Point;
  var st;
 
  SelToPath(1.0);   // Remove this line to only view paths


  Paths = app.activeDocument.pathItems;
  for (var i=0; i < Paths.length; i++) {
    Path = Paths[i];
    st = Path.name + "\nkind=" + Path.kind;
    SubPaths = Path.subPathItems;
    for (var j=0; j < SubPaths.length; j++) {
      Item = SubPaths[j];
      st += "\nSubPath " + j + " (" + Item.operation + ") ->";
      Points = Item.pathPoints;
     
      for (var k=0;k < Points.length;k++) {
        Point = Points[k];
        st +=   "\n   Point " + k + ":"
              + " kind=" + Point.kind
              + " x=" + Point.anchor[0] + ", y=" + Point.anchor[1]
              ;
      } // for
     
    } // for
    alert(st, ScriptName);
  } // for
 
} catch (e) {
  alert(e.message, ScriptName);
}

Partager cet article
Repost0
Published by Habaki - dans Scripts
/ / /

Ce script donne un exemple de plusieurs techniques de dessin/peinture par script.

  

Il suffit de copier le script ci-dessous dans un fichier .JSX et de le lancer sous Photoshop (Fichier/Scripts/Parcourir) pour voir se construire une image en couleur de ces voeux ! 

Avant le lancement il faut sélectionner dans PS une jolie brosse (une forme) qui servira de base au script.

Le choix de la brosse détermine une grande part de l'apparence finale.

Mais rien n'empêche d'essayer plusieurs brosses... 

 

Par choix, le script n'utilise que du tracé sous Photoshop (pas de filtre). J'espère que cela pourra être utile aux scripteurs.

 

Avant le source, voici quelques images réalisées avec des brosses différentes.

Mais comme beaucoup de paramètres sont tirés au hasard, les images seront différentes même avec la même brosse. Et puis c'est amusant de voir se dérouler le script et l'image se construire progressivement !

 

Pour modifier les couleurs, à vous de touiller le code.

 

happynewyear01 100a4

 

 

happynewyear04 100a4

 

happynewyear08 100a4

 

/************************************************************************
   Happy New Year
 ************************************************************************
 28/12/2010 Habaki V1r01 : Creation
 ************************************************************************/
var ScriptName= "Happy New Year";

var docW = 3500; // Width
var docH = 2360; // Height
var docRes = 300; // Resolution
var ColorBG = "FFFFFF";

var pathNb = 0;
var pathHNY;
var typeUnitsSaved, rulerUnitsSaved;
var Ratio = docRes / 72;
/*----------------------------------------------------------------------*
                        Draw line
 *----------------------------------------------------------------------*/

function DrawLine(doc, x1,y1,x2,y2)
{
  var line    = new Array(new PathPointInfo, new PathPointInfo);
  var subPath = new Array(new SubPathInfo);
  var path;
 
  x1 /= Ratio;
  y1 /= Ratio;
  x2 /= Ratio;
  y2 /= Ratio;
 
  //alert(x1 + ", " + y1 + "\n" + x2 + ", " + y2);
  line[0].kind   = PointKind.CORNERPOINT;
  line[0].anchor  = new Array(x1, y1);
  line[0].leftDirection  = line[0].anchor;
  line[0].rightDirection = line[0].anchor;
 
  line[1].kind   = PointKind.CORNERPOINT;
  line[1].anchor  = new Array(x2, y2);
  line[1].leftDirection  = line[1].anchor;
  line[1].rightDirection = line[1].anchor;
 
  subPath[0].operation = ShapeOperation.SHAPEADD;
  subPath[0].closed = false;
  subPath[0].entireSubPath = line;
 
  pathNb++;
  path = doc.pathItems.add("line"+pathNb, subPath);
  path.strokePath(ToolType.BRUSH, true);
  path.remove();
 
  return(0);
}
/*----------------------------------------------------------------------*
                        Draw Square
 *----------------------------------------------------------------------*/
function DrawSquare(doc, x1,y1, size)
{
  var line = new Array(new PathPointInfo,new PathPointInfo,new PathPointInfo,new PathPointInfo);
  var subPath = new Array(new SubPathInfo);
  var path;
  var r = Math.floor((Math.random() + 0.5) * size / Ratio);
 
  //x1 /= Ratio;
  //y1 /= Ratio;
 
  if (r > x1) r = x1;
  if (r > y1) r = y1;
  if (x1+r > docW) r = docW-x1-1;
  if (y1+r > docH) r = docH-y1-1;
 
  //alert(x1 + ", " + y1);
  line[0].kind   = PointKind.CORNERPOINT;
  line[0].anchor  = new Array(x1-r, y1-r);
  line[0].leftDirection  = line[0].anchor;
  line[0].rightDirection = line[0].anchor;
 
  line[1].kind   = PointKind.CORNERPOINT;
  line[1].anchor  = new Array(x1+r, y1-r);
  line[1].leftDirection  = line[1].anchor;
  line[1].rightDirection = line[1].anchor;
 
  line[2].kind   = PointKind.CORNERPOINT;
  line[2].anchor  = new Array(x1+r, y1+r);
  line[2].leftDirection  = line[2].anchor;
  line[2].rightDirection = line[2].anchor;
 
  line[3].kind   = PointKind.CORNERPOINT;
  line[3].anchor  = new Array(x1-r, y1+r);
  line[3].leftDirection  = line[3].anchor;
  line[3].rightDirection = line[3].anchor;
 
  subPath[0].operation = ShapeOperation.SHAPEADD;
  subPath[0].closed = true;
  subPath[0].entireSubPath = line;
 
  pathNb++;
  path = doc.pathItems.add("pt"+pathNb, subPath);
  //path.fillPath(app.foregroundColor);
  path.fillPath();
  path.remove();
 
  return(0);
}
/*----------------------------------------------------------------------*
   Wait
 *----------------------------------------------------------------------*/
function ForAWhile()
{
  DrawLine(app.activeDocument,-100,-100,-50,-50);
}
/*----------------------------------------------------------------------*
   Set Diameter
 *----------------------------------------------------------------------*/
function BrushDiameterSet(/* float */ Diam)
{
  var AD = new ActionDescriptor();
  var AR = new ActionReference();
  var AD2 = new ActionDescriptor();
 
  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 );
}
/*----------------------------------------------------------------------*
   Path
 *----------------------------------------------------------------------*/
var thePath = Array("HNY",PathKind.NORMALPATH
//SubPath 0 ->
,Array(ShapeOperation.SHAPEADD,true
,Array(507,234),Array(407,585),Array(309,1002),Array(479,1037),Array(715,1063)
,Array(817,1045),Array(901,1009),Array(978,971),Array(1050,902),Array(1051,863)
,Array(1047,809),Array(1037,764),Array(977,707),Array(866,613),Array(813,571)
,Array(875,553),Array(929,523),Array(973,476),Array(987,424),Array(981,386)
,Array(897,321),Array(834,266),Array(775,231),Array(655,221),Array(578,218)
) // SubPath
//SubPath 1 ->
,Array(ShapeOperation.SHAPESUBTRACT,true
,Array(639,343),Array(596,502),Array(669,477),Array(735,446),Array(790,416)
,Array(828,381),Array(847,337),Array(776,329),Array(713,325)
) // SubPath
//SubPath 2 ->
,Array(ShapeOperation.SHAPESUBTRACT,true
,Array(560,683),Array(508,928),Array(611,935),Array(692,921),Array(759,893)
,Array(848,858),Array(913,789),Array(922,742),Array(913,714),Array(901,703)
,Array(881,661),Array(853,639),Array(758,626),Array(677,630),Array(636,645)
,Array(589,663)
) // SubPath
//SubPath 3 ->
,Array(ShapeOperation.SHAPEADD,true
,Array(1224,680),Array(1160,740),Array(1134,787),Array(1117,841),Array(1121,891)
,Array(1131,940),Array(1181,971),Array(1256,1022),Array(1357,1052),Array(1450,1042)
,Array(1509,1017),Array(1553,971),Array(1565,921),Array(1550,879),Array(1522,830)
,Array(1469,775),Array(1403,719),Array(1336,679),Array(1301,657),Array(1255,659)
) // SubPath
//SubPath 4 ->
,Array(ShapeOperation.SHAPESUBTRACT,true
,Array(1390,774),Array(1337,796),Array(1303,828),Array(1276,880),Array(1268,922)
,Array(1275,960),Array(1295,981),Array(1321,975),Array(1343,961),Array(1375,935)
,Array(1406,893),Array(1426,830),Array(1428,789),Array(1409,773)
) // SubPath
//SubPath 5 ->
,Array(ShapeOperation.SHAPEADD,true
,Array(1671,665),Array(1575,949),Array(1724,1045),Array(1773,875),Array(1804,963)
,Array(1964,1060),Array(2167,721),Array(2058,585),Array(1871,869),Array(1800,759)
) // SubPath
//SubPath 6 ->
,Array(ShapeOperation.SHAPEADD,true
,Array(2217,623),Array(2085,964),Array(2233,1061),Array(2301,845),Array(2323,948)
,Array(2467,1043),Array(2655,703),Array(2559,554),Array(2375,824),Array(2330,721)
) // SubPath
//SubPath 7 ->
,Array(ShapeOperation.SHAPEADD,true
,Array(2777,604),Array(2595,971),Array(2739,1091),Array(3015,1095),Array(2907,983)
,Array(2771,973),Array(2808,895),Array(2988,913),Array(2879,786),Array(2855,787)
,Array(2873,741),Array(3215,715),Array(3139,557)
) // SubPath
//SubPath 8 ->
,Array(ShapeOperation.SHAPEADD,true
,Array(778,1174),Array(394,2031),Array(389,2035),Array(567,2070),Array(716,1738)
,Array(887,1741),Array(941,2073),Array(1120,2083),Array(886,1314)
) // SubPath
//SubPath 9 ->
,Array(ShapeOperation.SHAPESUBTRACT,true
,Array(824,1473),Array(740,1670),Array(867,1675)
) // SubPath
//SubPath 10 ->
,Array(ShapeOperation.SHAPEADD,true
,Array(1237,2091),Array(1064,2045),Array(1232,1431),Array(1354,1561),Array(1413,1717)
,Array(1612,1295),Array(1713,1447),Array(1483,2004),Array(1320,1931),Array(1303,1784)
,Array(1237,2069)
) // SubPath
//SubPath 11 ->
,Array(ShapeOperation.SHAPEADD,true
,Array(1815,1346),Array(1617,1914),Array(1785,1972),Array(1863,1713),Array(1884,1939)
,Array(2052,2006),Array(2351,1483),Array(2349,1452),Array(2364,1421),Array(2259,1277)
,Array(2236,1319),Array(2223,1370),Array(1998,1727),Array(1917,1472)
) // SubPath
//SubPath 12 ->
,Array(ShapeOperation.SHAPEADD,true
,Array(2223,1894),Array(2444,1324),Array(2663,1283),Array(2746,1438),Array(2549,1467)
,Array(2497,1589),Array(2554,1587),Array(2680,1704),Array(2464,1695),Array(2413,1835)
,Array(2498,1834),Array(2634,1926),Array(2388,1973)
) // SubPath
//SubPath 13 ->
,Array(ShapeOperation.SHAPEADD,true
,Array(2879,1305),Array(2629,1866),Array(2793,1969),Array(3199,1961),Array(3081,1858)
,Array(2806,1870),Array(2886,1680),Array(3123,1635),Array(3036,1516),Array(2933,1531)
,Array(2964,1444),Array(3397,1362),Array(3325,1225)
) // SubPath
//SubPath 14 ->
,Array(ShapeOperation.SHAPEADD,true
,Array(2552,1225),Array(2676,1136),Array(2724,1205),Array(2570,1256)
) // SubPath
);
/*----------------------------------------------------------------------*
   Build path from Data
 -> pathHNY
 *----------------------------------------------------------------------*/
function PathBuild(path)
{
  var spath;
  var line;
  var subPath;
  var pointInfo, pathInfo;
 
  subPath = new Array();
  for (var j=2;j<path.length;j++) {
    spath = path[j];
   
    line = new Array();
    for (var k=2;k<spath.length;k++) {
      pointInfo = new PathPointInfo();
      pointInfo.kind  = PointKind.CORNERPOINT;
      spath[k][0] /= Ratio;
      spath[k][1] /= Ratio;
      pointInfo.anchor  = spath[k];
      pointInfo.leftDirection = pointInfo.anchor;
      pointInfo.rightDirection = pointInfo.anchor;
      line[k-2] = pointInfo;
    } // for
   
    pathInfo = new SubPathInfo();
    pathInfo.operation = spath[0];
    pathInfo.closed = spath[1];
    pathInfo.entireSubPath = line;
    subPath[j-2] = pathInfo;
  } // for
  pathHNY = doc.pathItems.add(path[0], subPath);
  pathHNY.deselect();
  return(pathHNY);
}
/*----------------------------------------------------------------------*
   Main
 *----------------------------------------------------------------------*/
typeUnitsSaved  = app.preferences.typeUnits;
rulerUnitsSaved = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
app.preferences.typeUnits  = TypeUnits.PIXELS;

try {
  var doc;
  var x1,y1,x2,y2;
  var i, j;
  var LPath,L0, L1, L2, L3, LT;
  var color;
  var path0;
 
  if (confirm("Avant de Commencer, Selectionner une jolie brosse !"
              +"\nPar exemple le Brin d'Herbe..."
              +"\nEst-ce fait ?"
              +"\n(le script dure quelques minutes: selon la brosse et l'ordi !)"
              , true, ScriptName)) {
   
    app.backgroundColor.rgb.hexValue = ColorBG;
   
    doc = app.documents.add(docW,docH, docRes,
           "HappyNewYear",
           NewDocumentMode.RGB, DocumentFill.BACKGROUNDCOLOR);
    //doc = app.activeDocument;
   
    L0 = doc.activeLayer;
    L1=doc.artLayers.add();
    L1.name = "Lignes";
    L2=doc.artLayers.add();
    L2.name = "Contour";
    L3=doc.artLayers.add();
    L3.name = "Carres";
    LT=doc.artLayers.add();
    LT.name = "Sign";
    LT.kind = LayerKind.TEXT;
    LT.textItem.contents = "Habaki";
    LT.textItem.size = 20;
    LT.textItem.font = "Arial";
    LT.textItem.color.rgb.hexValue = "FFFFFF";
    LT.translate(docW*4/5, docH*4/5 + 100);
    LT.visible = false;
    LPath =doc.artLayers.add();
    LPath.name = ScriptName;
    doc.activeLayer = LPath;
   
    PathBuild(thePath);
    color = new SolidColor();
    color.rgb.hexValue = ColorBG;
    //pathHNY.fillPath(color);
    pathHNY.makeSelection();
    doc.selection.fill(color);
    doc.selection.deselect();
   
    BrushDiameterSet(docRes);
   
    // Lignes
    doc.activeLayer = L1;
    app.backgroundColor.rgb.hexValue = "000000";
    x1 = Math.random()*docW;
    y1 = Math.random()*docH;
    for (i=0;i<200;i++) {
      x2 = (Math.random()*1.4 - 0.2)*docW;
      y2 = (Math.random()*1.4 - 0.2)*docH;
      color = Math.floor(Math.random() * 0x0FFFFFF).toString(16);
      color = "000000".slice(0,6-color.length) + color;
      app.foregroundColor.rgb.hexValue = color;
      DrawLine(doc,x1,y1,x2,y2);
      x1 = x2;
      y1 = y2;
    } // for
   
    // Fond noir
    L0.invert();
    ForAWhile();
   
    // Rouge
    doc.activeLayer = L3;
    app.foregroundColor.rgb.hexValue = "FF0000";
    app.backgroundColor.rgb.hexValue = "000000";
    pathHNY.makeSelection();
    doc.selection.fill(app.foregroundColor);
    doc.selection.deselect();
    x2 = y2 = 0;
    for (i=2;i<thePath.length;i++) {
     path0 = thePath[i];
     if (path0[0] != ShapeOperation.SHAPEADD) continue;
     for (j=2;j<path0.length;j++) {
       app.foregroundColor.rgb.red = Math.floor(Math.random()*255);
        x1 = path0[j][0];
        y1 = path0[j][1];
        //alert(Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)));
        DrawSquare(doc,x1,y1,200);
        ForAWhile();
        x2 = x1;
        y2 = y1;
     } // for
    } // for
   
    pathHNY.makeSelection();
    doc.selection.invert();
    doc.selection.clear();
    doc.selection.deselect();
   
    LPath.visible = false;
   
    doc.activeLayer = L2;
    BrushDiameterSet(docRes/3);
    app.foregroundColor.rgb.hexValue = "FFFFFF";
    app.backgroundColor.rgb.hexValue = "FFFFFF";
    pathHNY.strokePath(ToolType.BRUSH, false);
    pathHNY.strokePath(ToolType.BRUSH, false);
   
    LT.visible = true;
    pathHNY.remove();
    LPath.remove();
    doc.flatten();
    //alert("Fini", ScriptName);
  }
} catch (e) {
  alert("Selectionner une Brosse svp !"
      + "\nC'est sans doute le probleme !");
  alert(e.message, ScriptName);
}
app.preferences.rulerUnits = rulerUnitsSaved;
app.preferences.typeUnits  = typeUnitsSaved;

 

Partager cet article
Repost0
Published by Habaki - dans Scripts
/ / /

This script prints into a file an action descriptor, an action reference or an action list with all parameters and types.

 

Action descriptors are the basic units of communication with Photoshop to do what is not possible with a normal script using classes and objects.

 

Action descriptors are also used to get many internal informations like for instance the opacity of the current brush among a lot of others.

 

Action descriptors are given as arguments to photoshop events and so allow to known what is the context of an event call. For instance on "open", an action descriptor gives the path name of the document .

 

The problem in using these powerfull descriptors is to known the format and the identifers that are not documented.

 

This is the purpose of this script: to show informations inside action descriptors and to give an example of how to do it.

 

/************************************************************************
   Action Viewer
 ************************************************************************
 Prints an action descriptor, action reference or action list with all
 arguments and types into a file and/or an alert box.
 IDs are printed as strings if possible ("Select") else as chars ('slct').
 ************************************************************************
 20/05/2010 Habaki V1r01 : Creation
 ************************************************************************/
var ScriptName = "Action Viewer, (c) Habaki 2010";

var FilePath   = "/c/PSActionD.txt"; // Full path of the output file
/*----------------------------------------------------------------------*
                        Num to String (enumeration value)
 *----------------------------------------------------------------------*/
function NumSt(Num)
{
  var St = app.typeIDToStringID(Num);
  if (St) return("\"" + St + "\"");
  St = app.typeIDToCharID(Num);
  if (St) return("'" + St + "'");
  return(String(Num));
}
/*----------------------------------------------------------------------*
                        ID to String
 *----------------------------------------------------------------------*/
function IDSt(ID)
{
  var St = app.typeIDToStringID(ID);
  if (St) return("\"" + St + "\"");
  return("'" + app.typeIDToCharID(ID) + "'");
}
/*----------------------------------------------------------------------*
                        Print Action Reference to string
 *----------------------------------------------------------------------*/
function AR_PrintSt(AR, Margin)
{
  var St = Margin;
  var Form;
  var ValSt, FormSt, ValClass, ValClassc;
 
  AR.getName();
  Form = AR.getForm();
  ValClass = app.typeIDToStringID(AR.getDesiredClass());
  ValClassc = app.typeIDToCharID(AR.getDesiredClass());
 
  if (Form == ReferenceFormType.CLASSTYPE) {
    FormSt = "Class";
    ValSt = ValClass;
  }
  else
  if (Form == ReferenceFormType.ENUMERATED) {
    FormSt = "Enumerated";
    Type = AR.getEnumeratedType();
    Val  = AR.getEnumeratedValue();
    ValSt = "(Type=" + IDSt(Type)
          + ", Val=" + NumSt(Val)
          + ")";
  }
  else
  if (Form == ReferenceFormType.IDENTIFIER) {
    FormSt = "Identifier";
    ValSt  = IDSt(AR.getIdentifier());
  }
  else
  if (Form == ReferenceFormType.INDEX) {
    FormSt = "Index";
    ValSt  = String(AR.getIndex());
  }
  else
  if (Form == ReferenceFormType.NAME) {
    FormSt = "Name";
    ValSt = "\"" + AR.getName() + "\"";
  }
  else
  if (Form == ReferenceFormType.OFFSET) {
    FormSt = "Offset";
    ValSt = String(AR.getOffset());
  }
  else
  if (Form == ReferenceFormType.PROPERTY) {
    FormSt = "Property";
    ValSt = IDSt(AR.getProperty());
  }
  else {
    FormSt = "??";
    ValSt = "??";
  }
 
  St += "Class=" + ValClass
     //+ "('" + ValClassc + "')" // CharID
     + ", " + FormSt + "=" + ValSt
     ;
  return(St);
}
/*----------------------------------------------------------------------*
   Print Descriptor
 *----------------------------------------------------------------------*/
function DS_PrintSt(DS, Key, Margin)
{
  var Val;
  var TypeSt = "?";
  var ValSt = "?";
  var Type = DS.getType(Key);
 
  if (Type == DescValueType.ALIASTYPE) {
    TypeSt = "Path";
    ValSt = DS.getPath(Key);
  }
  else
  if (Type == DescValueType.BOOLEANTYPE) {
    TypeSt = "Boolean";
    ValSt = DS.getBoolean(Key);
  }
  else
  if (Type == DescValueType.CLASSTYPE) {
    TypeSt = "Class";
    Type = DS.getClass(Key);
    ValSt = IDSt(Type);
  }
  else
  if (Type == DescValueType.DOUBLETYPE) {
    TypeSt = "Double";
    ValSt = String(DS.getDouble(Key));
  }
  else
  if (Type == DescValueType.ENUMERATEDTYPE) {
    TypeSt = "Enumerated";
    Type = DS.getEnumerationType(Key);
    Val  = DS.getEnumerationValue(Key);
    ValSt = "Type=" + IDSt(Type)
          + ", Val=" + NumSt(Val)
          ;
  }
  else
  if (Type == DescValueType.INTEGERTYPE) {
    TypeSt = "Integer";
    ValSt = String(DS.getInteger(Key));
  }
  else
  if (Type == DescValueType.LISTTYPE) {
    TypeSt = "List";
    Val = DS.getList(Key);
    ValSt = "\r"
          + AL_PrintSt(Val, Margin + "    ")
          //+ Margin
          ;
  }
  else
  if (Type == DescValueType.OBJECTTYPE) {
    TypeSt = "Object";
    Type = DS.getObjectType(Key);
    Val = DS.getObjectValue(Key);
    ValSt = "Type=" + IDSt(Type) + ",\r"
          + AD_PrintSt(Val, Margin + "    ")
          //+ Margin
          ;
  }
  else
  if (Type == DescValueType.RAWTYPE) {
    TypeSt = "Raw";
    ValSt = "{" + DS.getData(Key) + "}";
  }
  else
  if (Type == DescValueType.REFERENCETYPE) {
    TypeSt = "Reference";
    Val = DS.getReference(Key);
    ValSt = AR_PrintSt(Val, "");
  }
  else
  if (Type == DescValueType.STRINGTYPE) {
    TypeSt = "String";
    ValSt = "\"" + DS.getString(Key) + "\"";
  }
  else
  if (Type == DescValueType.UNITDOUBLE) {
    TypeSt = "UnitDouble";
    Type = DS.getUnitDoubleType(Key);
    ValSt = "Type=" + IDSt(Type)
          + ", Val=" + String(DS.getUnitDoubleValue(Key))
          ;
  }
  else {
    TypeSt = "Type";
    ValSt = DS.getType(Key);
  }
  return(TypeSt + "(" + ValSt + ")");
}
/*----------------------------------------------------------------------*
                        Print Action List to string
 *----------------------------------------------------------------------*/
function AL_PrintSt(AL, Margin)
{
  var Key;
  var St = "";
 
  for (Key=0;Key < AL.count; Key++) {
    St += Margin + "[" + String(Key) + "]:"
        + DS_PrintSt(AL, Key, Margin)
        ;
    if (Key == AL.count-1) St += "\r";
    else                   St += ",\r"
  } // for
  St += Margin;
  return(St);
}
/*----------------------------------------------------------------------*
                        Print Action Descriptor to string
 *----------------------------------------------------------------------*/
function AD_PrintSt(AD, Margin)
{
  var i;
  var St = "";
  var Key;
 
  for (i=0;i < AD.count; i++) {
    Key  = AD.getKey(i);
    St += Margin + "Key[" + String(i) + "]:" + IDSt(Key)
       + " = "
       + DS_PrintSt(AD, Key, Margin)
       ;
    if (i == AD.count-1) St += "\r";
    else                 St += ",\r"
  } // for
  St += Margin;
  return(St);
}
/*----------------------------------------------------------------------*
   Main
 Prints a main action descriptor.
 *----------------------------------------------------------------------*/
try {
  var ref = new ActionReference();
  ref.putEnumerated(charIDToTypeID("capp"),
                    charIDToTypeID("Ordn"),
                    charIDToTypeID("Trgt")
                    );
  // Everything
  var AD = executeActionGet(ref);
 
  // Current tool only
  //AD = AD.getObjectValue(stringIDToTypeID('currentToolOptions'));
 
  // Current brush only
  //AD = AD.getObjectValue(stringIDToTypeID('brush'));
 
  var St = AD_PrintSt(AD, "");
 
  var FF = new File(FilePath);
  FF.open("w:");
  FF.write(St);
  FF.close();
  FF.execute();
 
  //alert(St, ScriptName);
 
} catch(ex) {
  alert(ex.message);
}

Partager cet article
Repost0
Published by Habaki - dans Scripts
/ / /

Ce script découpe l'image du calque courant en tranches verticales, puis dispose les tranches en éventail en les ajustant à la dimension voulue.
Les tranches sont séparées par une marge et possèdent des coins arrondis.
L'image doit plutot etre en format paysage et assez allongée pour pouvoir etre disposée en un bel éventail.

Une interface utilisateur permet de définir les paramètres de cette transformation:
Nombre de morceaux, angle total, taille du cercle, marge entre morceaux, rayon de l'arrondi des coins.

Le script plus bas rassemble trois parties regroupées ici en une seule (PATHS, TRANSFRM et FAN), mais peut etre copié dans un seul fichier FAN.JSX.   

NOTE: Par modularité, il peut-etre utile de séparer ces parties en trois fichiers : PATHS.JSX, TRANSFRM.JSX et FAN.JSX.
Dans ce cas, les lignes "#include ..." au début de FAN.JSX doivent etre activées.
C'est ensuite FAN.JSX qui doit etre exécuté.

fan
venise
montagne
mars1

/************************************************************************
                        Fan
 ************************************************************************
 Build a fan with a wide image.
 ************************************************************************
 13/03/2010 V1r02b Habaki: Improve dialog
 12/03/2010 V1r02  Habaki: Add the fan angle
 09/03/2010 V1r01  Habaki: Creation
 ************************************************************************/
/************************************************************************
   PATHS.JSX
 ************************************************************************
 09/03/2010 Habaki V1r01 : Creation
 ************************************************************************/
/*----------------------------------------------------------------------*
   New Path on a rectangle
                        with Round corners
 *----------------------------------------------------------------------*/
function PathRect(
 Top, Left,Bottom,Right,
 CornerRadius
 )
{
      var idPxl = charIDToTypeID( "#Pxl" );
      var idsetd = charIDToTypeID( "setd" );
      var idnull = charIDToTypeID( "null" );
      var idPath = charIDToTypeID( "Path" );
      var idWrPt = charIDToTypeID( "WrPt" );
      var idT = charIDToTypeID( "T   " );
      //var idT = charIDToTypeID( "TyPa" );
      var idTop = charIDToTypeID( "Top " );
      var idLeft = charIDToTypeID( "Left" );
      var idBtom = charIDToTypeID( "Btom" );
      var idRght = charIDToTypeID( "Rght" );
      var idRds = charIDToTypeID( "Rds " );
      var idRctn = charIDToTypeID( "Rctn" );
     
      var ref4 = new ActionReference();
      ref4.putProperty( idPath, idWrPt );
     
      var desc0 = new ActionDescriptor();
      desc0.putReference( idnull, ref4 );
      var desc1 = new ActionDescriptor();
      desc1.putUnitDouble( idTop, idPxl, Top);
      desc1.putUnitDouble( idLeft, idPxl, Left);
      desc1.putUnitDouble( idBtom, idPxl, Bottom);
      desc1.putUnitDouble( idRght, idPxl, Right);
      desc1.putUnitDouble( idRds, idPxl, CornerRadius);
      desc0.putObject( idT, idRctn, desc1 );
      executeAction( idsetd, desc0, DialogModes.NO );
}
/*----------------------------------------------------------------------*/

/************************************************************************
   TRANSFORM.JSX
    Use Warp
 ************************************************************************
 Perform several transformations of a rectangle :
 Identity
 Trapezium
 First the transform grid must be computed. Then the warp use the last
 computed grid.
 ************************************************************************
 07/03/2010 Habaki V1r01 : Creation
 ************************************************************************/
/*----------------------------------------------------------------------*
   Constructor
 *----------------------------------------------------------------------*/
function Transform()
{
  this.lCur = app.activeDocument.activeLayer;
  var Bounds = this.lCur.bounds;
  this.top = Bounds[1];
  this.left = Bounds[0];
  this.bottom = Bounds[3];
  this.right = Bounds[2];
  // Grid nb of segments
  this.gridHNb = 3;
  this.gridVNb = 3;
  // Grid Unit
  this.gridHU = (this.right  - this.left) / this.gridHNb;
  this.gridVU = (this.bottom - this.top)  / this.gridVNb;
 
  // Warp grip : [V][H] : 0 1 2 3 / 4 5 6 7/ ...
  this.grid;
}
/*----------------------------------------------------------------------*
   Identity Grid
 *----------------------------------------------------------------------*/
Transform.prototype.gridIdentity = function()
{
  var grid = new Array();
  var pt, line;
  var h, v;
 
  for (v = 0;v <= this.gridVNb;v++) {
    line = new Array();
    for (h = 0;h <= this.gridHNb;h++) {
      pt = new Array();
      pt[0] = this.left + h* this.gridHU;
      pt[1] = this.top  + v* this.gridVU;
      line[h] = pt;
    }
    grid[v] = line;
  }
  return(grid);
}
/*----------------------------------------------------------------------*
   Trapezium grid
 *----------------------------------------------------------------------*/
Transform.prototype.gridTrapez = function(
        ScaleBottom  // Scale of bottom edge (%)
 )
{
  var grid = new Array();
  var pt, line;
  var h, v;
  var H, V;
 
  ScaleBottom /= 100.0;
  ScaleBottom = 1.0 - ScaleBottom;
  for (v = 0;v <=  this.gridVNb;v++) {
    line = new Array();
    for (h = 0;h <= this.gridHNb;h++) {
      pt = new Array();
      H = 1.0*h / this.gridHNb;
      V = 1.0*v / this.gridVNb;
      pt[0] = this.left
            + this.gridHU * this.gridHNb*(0.5 -
                                          (0.5 - H)*(1.0 - V*ScaleBottom));
      pt[1] = this.top  + this.gridVU * v;
     
      line[h] = pt;
    }
    grid[v] = line;
  }
  return(grid);
}
/*----------------------------------------------------------------------*
   Execute the warp
 *----------------------------------------------------------------------*/
Transform.prototype.warpExec = function() {
    var h,v;
    var line, pt;
   
    //-------- IDs
    var idTrnf = charIDToTypeID( "Trnf" );
    var idnull = charIDToTypeID( "null" );
    var idOfst = charIDToTypeID( "Ofst" );
    var idHrzn = charIDToTypeID( "Hrzn" );
    var idRlt = charIDToTypeID( "#Rlt" );
    var idVrtc = charIDToTypeID( "Vrtc" );
    var idwarp = stringIDToTypeID( "warp" );
    var idPxl = charIDToTypeID( "#Pxl" );
    var idrationalPoint = stringIDToTypeID( "rationalPoint" );
    var idwarp = stringIDToTypeID( "warp" );
    var idwarpStyle = stringIDToTypeID( "warpStyle" );
    var idwarpCustom = stringIDToTypeID( "warpCustom" );
    var idwarpValue = stringIDToTypeID( "warpValue" );
    var idwarpPerspective = stringIDToTypeID( "warpPerspective" );
    var idwarpPerspectiveOther = stringIDToTypeID( "warpPerspectiveOther" );
    var idwarpRotate = stringIDToTypeID( "warpRotate" );
    var idOrnt = charIDToTypeID( "Ornt" );
    var idbounds = stringIDToTypeID( "bounds" );
    var idTop = charIDToTypeID( "Top " );
    var idLeft = charIDToTypeID( "Left" );
    var idBtom = charIDToTypeID( "Btom" );
    var idRght = charIDToTypeID( "Rght" );
    var idRctn = charIDToTypeID( "Rctn" );
    var iduOrder = stringIDToTypeID( "uOrder" );
    var idvOrder = stringIDToTypeID( "vOrder" );
    var idcustomEnvelopeWarp = stringIDToTypeID( "customEnvelopeWarp" );
    var idmeshPoints = stringIDToTypeID( "meshPoints" );
    var idrationalPoint = stringIDToTypeID( "rationalPoint" );
    var idPath = charIDToTypeID( "Path" );
    var idOrdn = charIDToTypeID( "Ordn" );
    var idTrgt = charIDToTypeID( "Trgt" );
    var idFTcs = charIDToTypeID( "FTcs" );
    var idQCSt = charIDToTypeID( "QCSt" );
    var idQcsa = charIDToTypeID( "Qcsa" );
    //--------
    var desc15 = new ActionDescriptor();
    var ref8 = new ActionReference();
    ref8.putEnumerated( idPath, idOrdn, idTrgt );
    desc15.putReference( idnull, ref8 );
    desc15.putEnumerated( idFTcs, idQCSt, idQcsa );
    var desc16 = new ActionDescriptor();
    desc16.putUnitDouble( idHrzn, idRlt, 0.000000 );
    desc16.putUnitDouble( idVrtc, idRlt, 0.000000 );
    desc15.putObject( idOfst, idOfst, desc16 );
   
    var desc17 = new ActionDescriptor();
    desc17.putEnumerated( idwarpStyle, idwarpStyle, idwarpCustom );
    desc17.putDouble( idwarpValue, 0.00000 );
    desc17.putDouble( idwarpPerspective, 0.000000 );
    desc17.putDouble( idwarpPerspectiveOther, 0.000000 );
    desc17.putEnumerated( idwarpRotate, idOrnt, idHrzn );
   
    // Layer.bounds
    var desc18 = new ActionDescriptor();
    desc18.putUnitDouble( idTop,  idPxl, this.top); // [1] TopLeftY
    desc18.putUnitDouble( idLeft, idPxl, this.left); // [0] TopLeftx
    desc18.putUnitDouble( idBtom, idPxl, this.bottom); // [3] BottomRightY
    desc18.putUnitDouble( idRght, idPxl, this.right); // [2] BottomRightX
    desc17.putObject( idbounds, idRctn, desc18 );
    desc17.putInteger( iduOrder, this.gridHNb+1 );
    desc17.putInteger( idvOrder, this.gridVNb+1 );
   
    // List of mesh points
    // 0 1 2 3
    // 4 5 6 7
    // ...
    var list1 = new ActionList();
    for (v = 0;v <= this.gridVNb;v++) {
      line = this.grid[v];
      for (h = 0;h <= this.gridHNb;h++) {
        pt = line[h];
        var descPt = new ActionDescriptor();
        try{
          descPt.putUnitDouble( idHrzn, idPxl, pt[0]);
          descPt.putUnitDouble( idVrtc, idPxl, pt[1]);
        } catch(ex) {
          alert("==>" + ex.message + "<" + pt[0] + "," + pt[1] + ">");
        }
        list1.putObject( idrationalPoint, descPt );
      }
    }
    var desc19 = new ActionDescriptor();
    desc19.putList( idmeshPoints, list1 );
    desc17.putObject( idcustomEnvelopeWarp, idcustomEnvelopeWarp, desc19 );
    desc15.putObject( idwarp, idwarp, desc17 );
    executeAction( idTrnf, desc15, DialogModes.NO );
}
/************************************************************************
                        Fan
 ************************************************************************
 Build a fan with a wide image.
 ************************************************************************
 13/03/2010 V1r02b Habaki: Improve dialog
 12/03/2010 V1r02  Habaki: Add the fan angle
 09/03/2010 V1r01  Habaki: Creation
 ************************************************************************/
//#include "transfrm.jsx"
//#include "paths.jsx"

/*----------------------------------------------------------------------*
                        Constructor
 *----------------------------------------------------------------------*/
function Fan()
{
  this.FLName="Fan";     // Result layer name
  this.LRef  = app.activeDocument.activeLayer;  // Reference layer
 
  this.FPNb = 7;  // Number of pieces
  this.FRadius = 150;  // Radius of circle: % of image height (> 100)
  this.FCorner = 6.0;  // % of image height
  this.FMargin = 2.0;  // % of image height
  this.FAngle = 180;  // Angle of the fan (0..360dgs)
}
/*----------------------------------------------------------------------*
                        Dialog
 *----------------------------------------------------------------------*/
Fan.prototype.dialogBuild = function(
        )
{
  var Coord = this.LRef.bounds;
  var LHeight = Coord[3] - Coord[1];
  var LWidth  = Coord[2] - Coord[0];
 
  var myResource = "dialog{ \
    orientation: 'column',\
    alignChildren: 'fill',\
    panelLayer: Panel {\
      orientation: 'column',\
      alignChildren: 'fill',\
      text: 'IMAGE to Process',\
      Name: Group {\
        orientation: 'row',\
        Msg: StaticText {text: 'Layer: '},\
        Val: StaticText {text: ''}\
      },\
      Height: Group {\
        orientation: 'row',\
        Msg: StaticText {text: 'Height: ', characters: 25},\
        Val: StaticText {text: '?'}\
      },\
      Width: Group {\
        orientation: 'row',\
        Msg: StaticText {text: 'Width', characters: 25},\
        Val: StaticText {text: '?'}\
      }\
    },\
    panelCircle: Panel  {\
      orientation: 'column',\
      alignChildren: 'fill',\
      text: 'FAN',\
      Nb: Group {\
        orientation: 'row',\
        Msg: StaticText {text: 'Nb of pieces:', characters: 25},\
        Val: EditText {text: '7', bounds: [0,0,40,20]}\
      },\
      Angle: Group {\
        orientation: 'row',\
        Msg: StaticText {text: 'Fan angle (dgs):', characters: 25},\
        Val: EditText { text: '180', bounds: [0,0,40,20]}\
      },\
      s00: StaticText {text: 'All % are relative to image Height.', characters: 35 },\
      Rad: Group {\
        orientation: 'row',\
        Msg: StaticText {text: 'Circle radius (% > 100):', characters: 25},\
        Val: EditText { text: '150', bounds: [0,0,40,20]},\
      },\
      Corn: Group {\
        orientation: 'row',\
        Msg: StaticText {text: 'Corner radius (%):', characters: 25 },\
        Val: EditText { text: '6', bounds: [0,0,40,20]},\
      },\
      Marg: Group {\
        orientation: 'row',\
        Msg: StaticText {text: 'Margin between pieces (%):' , characters: 25},\
        Val: EditText { text: '2', bounds: [0,0,40,20] }\
      }\
    },\
    sign: StaticText {text: 'Habaki (c) 2010', characters: 15 },\
    groupButtons: Group  {\
      orientation: 'row',\
      buttonOk: Button { text: 'Build', enabled: 'false'},\
      buttonCancel: Button { text: 'Cancel'},\
    }\
  };"
  var myDialog = new Window(myResource, "  Build a FAN");
  myDialog.fanInstance = this;
 
  myDialog.panelLayer.Name.Val.text = this.LRef.name;
  myDialog.panelLayer.Height.Val.text = LHeight;
  myDialog.panelLayer.Width.Val.text = LWidth;
 
  myDialog.panelCircle.Angle.Val.text = "" + this.FAngle;
  myDialog.panelCircle.Rad.Val.text = "" + this.FRadius;
  myDialog.panelCircle.Corn.Val.text = "" + this.FCorner;
  myDialog.panelCircle.Marg.Val.text = "" + this.FMargin*2;
 
  // determines return value and keyboard shortcuts
  myDialog.defaultElement = myDialog.groupButtons.buttonOk; // == return value 1
  myDialog.cancelElement  = myDialog.groupButtons.buttonCancel;
  /*--------------------------------------------------*/
  return myDialog
}
/*----------------------------------------------------------------------*
                Get parameters from User
 *----------------------------------------------------------------------*/
Fan.prototype.getParams = function() 
{
  var Doc = app.activeDocument;
  var LNb;
  var i;
  var LL;
 
  var myDialog = this.dialogBuild();
  var OK = (myDialog.show() == 1) ? true : false;
 
  if (OK) {
    this.FPNb    = parseInt(myDialog.panelCircle.Nb.Val.text);
    this.FAngle  = parseFloat(myDialog.panelCircle.Angle.Val.text);
    this.FRadius = parseFloat(myDialog.panelCircle.Rad.Val.text);
    this.FCorner = parseFloat(myDialog.panelCircle.Corn.Val.text);
    this.FMargin = parseFloat(myDialog.panelCircle.Marg.Val.text)/2;
  }
  return (OK);
}
/*----------------------------------------------------------------------*
                        Build process
 *----------------------------------------------------------------------*/
Fan.prototype.build = function()
{
  try{
    // Config parameters
    var LRef   = this.LRef; // Reference layer
   
    // Computed values
    var FRadE;   // External radius
    var FRadI;   // Internal radius
    var LWE, LWI;  // External,Internal widths for a piece
    var FCntX, FCntY;  // Fan center
    var LAngl0;   // Angle of a piece
    var LHeight, LWidth, LTX, LTY, LW;
    var FL, LL;   // layers
    var Coord;
    var i;
    var pathItem;
    var FMarg, FCorn;
   
    var PI = 3.14159265;
    var Doc = app.activeDocument;
    var Sel = Doc.selection;
   
    // Fan position (Center):
    FCntX = Doc.width /2;  // Horizontal
    FCntY = Doc.height*4/5; // Vertical
   
    // Dimension of the image
    // Coord: TopLeftX,TopLeftY,BottomRightX,BottomRightY
    Coord = LRef.bounds;
    LHeight = Coord[3] - Coord[1];
    LWidth  = Coord[2] - Coord[0];
   
    if (this.FRadius < 100) this.FRadius = 100;
    FRadE = LHeight*this.FRadius/100; // External radius
    FRadI = FRadE - LHeight;  // Internal radius
    LWE = FRadE * 2 * Math.sin(PI*this.FAngle / (this.FPNb * 360));
    LWI = LWE * FRadI / FRadE;
    FMarg = LHeight * this.FMargin / 100;
    FCorn = LHeight * this.FCorner / 100;
   
    var Tf = new Transform();
    Tf.grid = Tf.gridTrapez(LWI * 100.0 / LWE);
   
    // Result layer
    FL = Doc.artLayers.add();
    FL.name = this.FLName;
   
    // Split image in pieces
    LW  = LWidth/ this.FPNb;
    LTX = Coord[0];
    LTY = Coord[1];
    LAngl0 = PI*this.FAngle / (this.FPNb*180);
    for (i=0; i < this.FPNb; i++) {
      //alert("W:" + LW + ", X:" + LTX + ", Y:" + LTY);
     
      // Make a path with rounder corners to cut a piece
      PathRect(LTY, LTX+FMarg, LTY+LHeight, LTX+LW-FMarg, FCorn);
      pathItem = Doc.pathItems[0];
      pathItem.makeSelection();
      pathItem.remove();
     
      // Cut a piece
      LL = LRef.duplicate();
      Doc.activeLayer = LL;
      Sel.invert();
      Sel.clear();
      Sel.deselect();
     
      // Scale
      LL.resize(LWE*100 / LW,
                (FRadE - FRadI) * 100 / LHeight,
                AnchorPosition.TOPCENTER);
      // Trapezium
      Tf.warpExec();
     
      // Move TopCenter
      LL.translate(FCntX - LTX -LW/2
                   + FRadE*(Math.cos(PI - LAngl0*(i)) +
                            Math.cos(PI - LAngl0*(i+1)) )/2
                   ,
                   FCntY - LTY
                   - FRadE*(Math.sin(PI - LAngl0*(i)) +
                            Math.sin(PI - LAngl0*(i+1)) )/2
                   );
     
      // Rotate
      LL.rotate(this.FAngle*(i + 0.5)/this.FPNb -90, AnchorPosition.TOPCENTER);
     
      // Merge with the result
      LL.move(FL, ElementPlacement.PLACEBEFORE);
      LL.merge();
     
      // Another piece
      LTX += LW;
    } // for
   
  } catch(ex){
    alert(ex.message);
  }
}
/*----------------------------------------------------------------------*
                        Execution
 *----------------------------------------------------------------------*/
var RulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;

var fan = new Fan();

if (fan.getParams())
  fan.build();

app.preferences.rulerUnits = RulerUnits;
/*----------------------------------------------------------------------*/

Partager cet article
Repost0
Published by Habaki - dans Scripts