SlideShare ist ein Scribd-Unternehmen logo
1 von 42
HDTR images with
PhotoShop
Javascript
Dr Jeckyll & Mr Hide
Haciendo Fotos
desde los 16 años
Exposiciones
Colectivas e indivudales
Ing. técnico en
Informática de sistemas
Sw Engineer & Trainer
@dgomezg@d_v_g
The HDTR technique
Term coined by Martin Krzywinski
HDTR
High Dynamic
Time Range
The HDTR Technique
Term coined by Martin KrzywinskiHDTR | High Dynamic
Time Range
http://mkweb.bcgsc.ca/fun/hdtr/
Steps
SHOT
Process
Plan
The Planning
Spot the place
(Find out if its going to
be crowded at sunset)
Find out
when and where
the sun sets
Check the
weather forecast
(A rainy sunset looks
quite different)
When and Where
the sun sets
Photographic Shot
Keep the camera steady
for several hours
(a TRIPOD will help)
Set a
NEUTRAL White Balace
Keep a const Depth of
Field (Aperture Priority)
Better if you can shot
Tethered to a Computer
Pick some BEERS & FRIENDS
(but pay attention to the camera)
TOOLS and Setup
Tethered Shooting
Set Aperture Priority
Set timered shooting
(TIMELAPSE SHOOTING)
RESULTSRESULTS
Construction of a
HDTR image
The Photoshop Process
Described at
http://mkweb.bcgsc.ca/fun/hdtr/?tutorial
Automate the
process
Available AT
http://mkweb.bcgsc.ca/fun/hdtr/?CODE
Martin Krzywinski
Implementation
• Perl BASED
• PROS
• Easy setup &
RUN
• FREE
• No dependencies
(but Perl & libs)
• CONS
• Verbose
blending
config
• No tuning
posibility of
result image
PS Scripting
alternative
• PROS
• Final image un
PSD format with
layers
• You could
further adjust
the result
• Easy config & run
• CONS
• PS License
required
• Harder to code
PS scripting languages
Photoshop JS
• Since PHOTOSHOP CS 1
(experimental support in PS 7.0 via an optional
plugin)
• Cross platform
• New DOM To access most of Photoshop
features and properties
Photoshop’s DOM
• BUT Still some operations not
available: Gradients, Adjustment
Layers, Layer Effects, polygonal
selections....
Access to the “Hidden”
functionality
• JS Classes from original PS SDK
interface
• ActionDescriptor,
• ActionList
• ActionReference
• Use codes as parameters
Access to the “Hidden” functionality
ScriptListener plugin
//-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐
var	
  V1	
  =	
  new	
  ActionDescriptor();
var	
  V2	
  =	
  new	
  ActionDescriptor();
V2.putUnitDouble(charIDToTypeID("Hrzn"),charIDToTypeID("#Pxl"),	
  345);	
  
V2.putUnitDouble(charIDToTypeID("Vrtc"),charIDToTypeID("#Pxl"),	
  667);
V1.putObject(charIDToTypeID("From"),charIDToTypeID("Pnt	
  "),	
  V2);
var	
  V3	
  =	
  new	
  ActionDescriptor();
[...]
Records User’s interaction to JS script
var fillWithGradient = function(startX, startY, endX, endY) {
var V1 = new ActionDescriptor();
var V2 = new ActionDescriptor();
V2.putUnitDouble(
charIDToTypeID("Hrzn"),
charIDToTypeID("#Pxl"),
startX); // start point X
V2.putUnitDouble(
charIDToTypeID("Vrtc"),
charIDToTypeID("#Pxl"),
startY); // start point Y
V1.putObject(
charIDToTypeID("From"),
charIDToTypeID("Pnt "), V2);
var V3 = new ActionDescriptor();
Access to the “Hidden” functionality
Code translation
//-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐
var	
  V1	
  =	
  new	
  ActionDescriptor();
var	
  V2	
  =	
  new	
  ActionDescriptor();
V2.putUnitDouble(charIDToTypeID("Hrzn"),charIDToTypeID("#Pxl"),	
  345);	
  
V2.putUnitDouble(charIDToTypeID("Vrtc"),charIDToTypeID("#Pxl"),	
  667);
V1.putObject(charIDToTypeID("From"),charIDToTypeID("Pnt	
  "),	
  V2);
var	
  V3	
  =	
  new	
  ActionDescriptor();
[...]
Translating codes
/*
lMID.maskHides = 1214529900;//"HdAl"
lMID.maskRevealsAll = 1383492673;//"RvlA"
lMID.maskReveals = 1383492691;//"Rvls"
lMID.mask = 1299409696;//"Msk "
lMID.at = 1098129440;//"At "
lMID.using = 1433628263;//"Usng"
lMID.userMask = 1433629261;//"UsrM"
lMID.make = 1298866208;//"Mk "
lMID.property = 1349677170;//"Prpr"
...
*/
cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };
Photoshop Extended
Script
• SOME Photoshop classes are defined in
an extended an particular way
alert(app.activeDocument.height);
#include	
  "modules/json/json.js"
alert(JSON.stringify(app.activeDocument.height));
Photoshop
ExtendScript
.JSX .JS
Convention
ExtendScript files Regular files
not using special Adobe
classes and functions
DEVELOPMENT TOOLS
ExtendScript Toolkit
DEVELOPMENT TOOLS
ExtendScript Toolkit
• Delivered with every Creative Suite
product
• Need to set the target application
• Combo
• #target
• Benefits
• run on application
• Debug tools
• Inspector
DEVELOPMENT TOOLS
Any other JS editor
Launch script via File > Scripts > Browse ...
the Photoshop
HDTR.jsx script
Process config
var	
  hdtrConfig	
  =	
  {
	
  	
  	
  	
  direction	
  :	
  Direction.VERTICAL
	
  	
  	
  	
  ,	
  maskOffset	
  :	
  25
	
  	
  	
  	
  ,	
  guideSpacing	
  :	
  function	
  ()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  if	
  (this.direction	
  ==	
  Direction.VERTICAL)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  this.docDimensions.width	
  /	
  this.shots;
	
  	
  	
  	
  	
  	
  	
  	
  }	
  else	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  this.docDimensions.height	
  /	
  this.shots;
	
  	
  	
  	
  	
  	
  	
  	
  }
	
  	
  	
  	
  }
};
Added later:
- Image (document) dimensions
- Number of original shots
- Blending Offset (in Pixels)
Source file selection
& further config
var files = app.openDialog();
hdtrConfig.shots = files.length;
hdtrConfig.docDimensions = getImageFileDimensions(files[0]);
hdtrConfig.offset =
hdtrConfig.maskOffset * hdtrConfig.guideSpacing();
var getImageFileDimensions = function(file) {
	 var imageDocument = app.open(file);
	 var documentDimensions = { "height" : document.height,
	 	 	 "width" : document.width,
	 	 	 "resolution" : document.resolution};
	 imageDocument.close();
	 return documentDimensions;
}
HDTR document
var	
  hdtrDocument	
  =	
  app.documents.add(
hdtrConfig.docDimensions.width,	
  
hdtrConfig.docDimensions.height,
hdtrConfig.docDimensions.resolution);
drawGuides(hdtrDocument,	
  hdtrConfig.direction,	
  hdtrConfig.shots);
var	
  drawGuides	
  =	
  function(document,	
  direction,	
  number)	
  {
	
   var	
  distance	
  =	
  (direction	
  ==	
  Direction.HORIZONTAL)?
document.height	
  /	
  number	
  :
document.width	
  /	
  number	
  ;
	
   for	
  (var	
  i	
  =	
  0;	
  i	
  <	
  number	
  +	
  1;	
  i++)	
  {
	
   	
   var	
  position;
	
   	
   position	
  =	
  i	
  *	
  distance;
	
   	
   document.guides.add(direction,	
  
new	
  UnitValue(position,	
  position));
	
   }
}
Main Loop
var	
  refGuide;
var	
  from;
var	
  to;
for	
  (index	
  =	
  0;	
  index	
  <	
  files.length;	
  index++)	
  {
	
  	
  	
  	
  addLayerFromFile(hdtrDocument,	
  files[index]);
	
  	
  	
  	
  if	
  (index	
  >	
  0)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  refGuide	
  =	
  hdtrDocument.guides[index];
	
  	
  	
  	
  	
  	
  	
  	
  from	
  =	
  refGuide.coordinate	
  -­‐	
  hdtrConfig.offset;
	
  	
  	
  	
  	
  	
  	
  	
  to	
  =	
  refGuide.coordinate	
  +	
  hdtrConfig.offset;
	
  	
  	
  	
  	
  	
  	
  	
  createLayerMask(hdtrDocument,	
  hdtrDocument.activeLayer,	
  false);
	
  	
  	
  	
  	
  	
  	
  	
  fillWithGradient(from,	
  hdtrConfig.docDimensions.height	
  /2,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  to,	
  hdtrConfig.docDimensions.height	
  /2);
	
  	
  	
  	
  }
}
Add Layer from File
var	
  addLayerFromFile	
  =	
  function(hdtrDocument,	
  file)	
  {
	
  	
  	
  	
  var	
  sourceDocument	
  =	
  app.open(file);
	
  	
  	
  	
  app.activeDocument	
  =	
  sourceDocument;
	
  	
  	
  	
  app.activeDocument.activeLayer.copy();
	
  	
  	
  	
  app.activeDocument	
  =	
  hdtrDocument;
	
  	
  	
  	
  hdtrDocument.paste();
	
  	
  	
  	
  hdtrDocument.activeLayer.name	
  =	
  
(hdtrDocument.artLayers.length	
  -­‐1)	
  +	
  "-­‐"	
  +	
  sourceDocument.name;
	
  	
  	
  	
  sourceDocument.close();
}
Create Layer Mask
var	
  createLayerMask	
  =	
  function(doc,	
  layer,	
  fromSelection)	
  {
	
  	
  	
  	
  var	
  desc	
  =	
  new	
  ActionDescriptor();
	
  	
  	
  	
  desc.putClass(cTID("Nw	
  	
  "),	
  cTID("Chnl"));
	
  	
  	
  	
  
	
  	
  	
  	
  var	
  ref	
  =	
  new	
  ActionReference();
	
  	
  	
  	
  ref.putEnumerated(cTID("Chnl"),	
  cTID("Chnl"),	
  cTID("Msk	
  "));
	
  	
  	
  	
  desc.putReference(cTID("At	
  	
  "),	
  ref);
	
  	
  	
  	
  
	
  	
  	
  	
  if	
  (fromSelection	
  ==	
  true)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  desc.putEnumerated(cTID("Usng"),	
  cTID("UsrM"),	
  cTID("RvlS"));
	
  	
  	
  	
  }	
  else	
  {
	
  	
  	
  	
  	
  	
  	
  	
  desc.putEnumerated(cTID("Usng"),	
  cTID("UsrM"),	
  cTID("RvlA"));
	
  	
  	
  	
  }
	
  	
  	
  	
  executeAction(cTID("Mk	
  	
  "),	
  desc,	
  DialogModes.NO);
}
Fill with Gradient
var fillWithGradient = function(startX, startY, endX, endY) {
var V1 = new ActionDescriptor();
var V2 = new ActionDescriptor();
V2.putUnitDouble(
charIDToTypeID("Hrzn"),
charIDToTypeID("#Pxl"),
startX); // start point X
V2.putUnitDouble(
charIDToTypeID("Vrtc"),
charIDToTypeID("#Pxl"),
startY); // start point Y
V1.putObject(
charIDToTypeID("From"),
charIDToTypeID("Pnt "), V2);
var V3 = new ActionDescriptor();
....
Better to see the source code
DEMO TIME!
Next Steps
Heterogeneous slice
distribution
Easier configuration
Using Photoshop UI
Photoshop CS1
User Interaction via Alerts
Photoshop CS2
Added ScriptUI
(page 187 of PS CS2 JS Reference)
Photoshop CS3+
ScriptUI moved to PS JS TOOLS GUIDE
Script UI
var	
  dlg	
  =	
  new	
  Window("dialog{text:'Script	
  Interface',bounds:
[100,100,561,269],
iwtfkhamhc:EditText{bounds:[16,16,444.95,94]	
  ,	
  text:'Your	
  text	
  goes	
  
here'	
  ,properties:{multiline:false,noecho:false,readonly:false}},
button0:Button{bounds:[17,102,117,122]	
  ,	
  text:'Save'	
  },
button1:Button{bounds:[236,101,336,121]	
  ,	
  text:'Cancel'	
  },
button2:Button{bounds:[345,101,445,121]	
  ,	
  text:'Whatever'	
  },
slider0:Slider{bounds:[18,138,173,148]	
  ,	
  minvalue:0,maxvalue:100,value:
0},
checkbox0:Checkbox{bounds:[190,133,261,154]	
  ,	
  text:'Checkbox	
  Text'	
  },
dropdown0:DropDownList{bounds:[299,134,443,149],properties:{items:
['Select	
  One']}}
};");
dlg.show();
Further Reference
http://kcy.me/l7uohttp://kcy.me/l7ur
Q & A
Thanks
@d_v_g
@dgomezg
https://github.com/dgomezg/hdtr-photoshop-js

Weitere ähnliche Inhalte

Was ist angesagt?

Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash courseCodepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash courseSages
 
Using Change Streams to Keep Up with Your Data
Using Change Streams to Keep Up with Your DataUsing Change Streams to Keep Up with Your Data
Using Change Streams to Keep Up with Your DataEvan Rodd
 
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneBang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneDroidConTLV
 
Ken 20150306 心得分享
Ken 20150306 心得分享Ken 20150306 心得分享
Ken 20150306 心得分享LearningTech
 
Time Series Analysis by JavaScript LL matsuri 2013
Time Series Analysis by JavaScript LL matsuri 2013 Time Series Analysis by JavaScript LL matsuri 2013
Time Series Analysis by JavaScript LL matsuri 2013 Daichi Morifuji
 
Reutov, yunusov, nagibin random numbers take ii
Reutov, yunusov, nagibin   random numbers take iiReutov, yunusov, nagibin   random numbers take ii
Reutov, yunusov, nagibin random numbers take iiDefconRussia
 
Developing applications with rules, workflow and event processing (it@cork 2010)
Developing applications with rules, workflow and event processing (it@cork 2010)Developing applications with rules, workflow and event processing (it@cork 2010)
Developing applications with rules, workflow and event processing (it@cork 2010)Geoffrey De Smet
 
MongoDB Live Hacking
MongoDB Live HackingMongoDB Live Hacking
MongoDB Live HackingTobias Trelle
 
How to make a high-quality Node.js app, Nikita Galkin
How to make a high-quality Node.js app, Nikita GalkinHow to make a high-quality Node.js app, Nikita Galkin
How to make a high-quality Node.js app, Nikita GalkinSigma Software
 
[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)croquiscom
 
Embracing the-power-of-refactor
Embracing the-power-of-refactorEmbracing the-power-of-refactor
Embracing the-power-of-refactorXiaojun REN
 
(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your GroovyAlonso Torres
 
FwDays 2021: Metarhia Technology Stack for Node.js
FwDays 2021: Metarhia Technology Stack for Node.jsFwDays 2021: Metarhia Technology Stack for Node.js
FwDays 2021: Metarhia Technology Stack for Node.jsTimur Shemsedinov
 
Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?
Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?
Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?SegFaultConf
 

Was ist angesagt? (19)

Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash courseCodepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
 
Using Change Streams to Keep Up with Your Data
Using Change Streams to Keep Up with Your DataUsing Change Streams to Keep Up with Your Data
Using Change Streams to Keep Up with Your Data
 
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneBang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
 
Ken 20150306 心得分享
Ken 20150306 心得分享Ken 20150306 心得分享
Ken 20150306 心得分享
 
Time Series Analysis by JavaScript LL matsuri 2013
Time Series Analysis by JavaScript LL matsuri 2013 Time Series Analysis by JavaScript LL matsuri 2013
Time Series Analysis by JavaScript LL matsuri 2013
 
JEE on DC/OS
JEE on DC/OSJEE on DC/OS
JEE on DC/OS
 
Hack ASP.NET website
Hack ASP.NET websiteHack ASP.NET website
Hack ASP.NET website
 
Reutov, yunusov, nagibin random numbers take ii
Reutov, yunusov, nagibin   random numbers take iiReutov, yunusov, nagibin   random numbers take ii
Reutov, yunusov, nagibin random numbers take ii
 
Developing applications with rules, workflow and event processing (it@cork 2010)
Developing applications with rules, workflow and event processing (it@cork 2010)Developing applications with rules, workflow and event processing (it@cork 2010)
Developing applications with rules, workflow and event processing (it@cork 2010)
 
MongoDB Live Hacking
MongoDB Live HackingMongoDB Live Hacking
MongoDB Live Hacking
 
Return of c++
Return of c++Return of c++
Return of c++
 
How to make a high-quality Node.js app, Nikita Galkin
How to make a high-quality Node.js app, Nikita GalkinHow to make a high-quality Node.js app, Nikita Galkin
How to make a high-quality Node.js app, Nikita Galkin
 
[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)
 
How Not to Code
How Not to CodeHow Not to Code
How Not to Code
 
Embracing the-power-of-refactor
Embracing the-power-of-refactorEmbracing the-power-of-refactor
Embracing the-power-of-refactor
 
(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy
 
Jersey Guice AOP
Jersey Guice AOPJersey Guice AOP
Jersey Guice AOP
 
FwDays 2021: Metarhia Technology Stack for Node.js
FwDays 2021: Metarhia Technology Stack for Node.jsFwDays 2021: Metarhia Technology Stack for Node.js
FwDays 2021: Metarhia Technology Stack for Node.js
 
Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?
Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?
Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?
 

Ähnlich wie HDTR images with Photoshop Javascript Scripting

NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)Chris Richardson
 
Deep dive into deeplearn.js
Deep dive into deeplearn.jsDeep dive into deeplearn.js
Deep dive into deeplearn.jsKai Sasaki
 
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]Dimitrios Platis
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Paco de la Cruz
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02PL dream
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScriptQiangning Hong
 
Deep Dumpster Diving
Deep Dumpster DivingDeep Dumpster Diving
Deep Dumpster DivingRonnBlack
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksMongoDB
 
Ingesting and Manipulating Data with JavaScript
Ingesting and Manipulating Data with JavaScriptIngesting and Manipulating Data with JavaScript
Ingesting and Manipulating Data with JavaScriptLucidworks
 
Hack an ASP .NET website? Hard, but possible!
Hack an ASP .NET website? Hard, but possible! Hack an ASP .NET website? Hard, but possible!
Hack an ASP .NET website? Hard, but possible! Vladimir Kochetkov
 

Ähnlich wie HDTR images with Photoshop Javascript Scripting (20)

NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)
 
Deep dive into deeplearn.js
Deep dive into deeplearn.jsDeep dive into deeplearn.js
Deep dive into deeplearn.js
 
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)
 
NvFX GTC 2013
NvFX GTC 2013NvFX GTC 2013
NvFX GTC 2013
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
Dex Technical Seminar (April 2011)
Dex Technical Seminar (April 2011)Dex Technical Seminar (April 2011)
Dex Technical Seminar (April 2011)
 
Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
WebXR if X = how?
WebXR if X = how?WebXR if X = how?
WebXR if X = how?
 
Deep Dumpster Diving
Deep Dumpster DivingDeep Dumpster Diving
Deep Dumpster Diving
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Fact, Fiction, and FP
Fact, Fiction, and FPFact, Fiction, and FP
Fact, Fiction, and FP
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
Ingesting and Manipulating Data with JavaScript
Ingesting and Manipulating Data with JavaScriptIngesting and Manipulating Data with JavaScript
Ingesting and Manipulating Data with JavaScript
 
A More Flash Like Web?
A More Flash Like Web?A More Flash Like Web?
A More Flash Like Web?
 
srgoc
srgocsrgoc
srgoc
 
Hack an ASP .NET website? Hard, but possible!
Hack an ASP .NET website? Hard, but possible! Hack an ASP .NET website? Hard, but possible!
Hack an ASP .NET website? Hard, but possible!
 

Mehr von David Gómez García

Leverage CompletableFutures to handle async queries. DevNexus 2022
Leverage CompletableFutures to handle async queries. DevNexus 2022Leverage CompletableFutures to handle async queries. DevNexus 2022
Leverage CompletableFutures to handle async queries. DevNexus 2022David Gómez García
 
Building Modular monliths that could scale to microservices (only if they nee...
Building Modular monliths that could scale to microservices (only if they nee...Building Modular monliths that could scale to microservices (only if they nee...
Building Modular monliths that could scale to microservices (only if they nee...David Gómez García
 
Building modular monoliths that could scale to microservices (only if they ne...
Building modular monoliths that could scale to microservices (only if they ne...Building modular monoliths that could scale to microservices (only if they ne...
Building modular monoliths that could scale to microservices (only if they ne...David Gómez García
 
Leveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyLeveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyDavid Gómez García
 
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021Builiding Modular monoliths that can scale to microservices. JBCNConf 2021
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021David Gómez García
 
Cdm mil-18 - hypermedia ap is for headless platforms and data integration
Cdm mil-18 - hypermedia ap is for headless platforms and data integrationCdm mil-18 - hypermedia ap is for headless platforms and data integration
Cdm mil-18 - hypermedia ap is for headless platforms and data integrationDavid Gómez García
 
What's in a community like Liferay's
What's in a community like Liferay'sWhat's in a community like Liferay's
What's in a community like Liferay'sDavid Gómez García
 
Java9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadJava9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadDavid Gómez García
 
Managing user's data with Spring Session
Managing user's data with Spring SessionManaging user's data with Spring Session
Managing user's data with Spring SessionDavid Gómez García
 
Construccion de proyectos con gradle
Construccion de proyectos con gradleConstruccion de proyectos con gradle
Construccion de proyectos con gradleDavid Gómez García
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.David Gómez García
 
Midiendo la calidad de código en WTF/Min (Revisado EUI Abril 2014)
Midiendo la calidad de código en WTF/Min (Revisado EUI Abril 2014)Midiendo la calidad de código en WTF/Min (Revisado EUI Abril 2014)
Midiendo la calidad de código en WTF/Min (Revisado EUI Abril 2014)David Gómez García
 
Measuring Code Quality in WTF/min.
Measuring Code Quality in WTF/min. Measuring Code Quality in WTF/min.
Measuring Code Quality in WTF/min. David Gómez García
 
El poder del creador de Software. Entre la ingeniería y la artesanía
El poder del creador de Software. Entre la ingeniería y la artesaníaEl poder del creador de Software. Entre la ingeniería y la artesanía
El poder del creador de Software. Entre la ingeniería y la artesaníaDavid Gómez García
 
A real systemwithjms-rest-protobuf-mongodb
A real systemwithjms-rest-protobuf-mongodbA real systemwithjms-rest-protobuf-mongodb
A real systemwithjms-rest-protobuf-mongodbDavid Gómez García
 

Mehr von David Gómez García (20)

Leverage CompletableFutures to handle async queries. DevNexus 2022
Leverage CompletableFutures to handle async queries. DevNexus 2022Leverage CompletableFutures to handle async queries. DevNexus 2022
Leverage CompletableFutures to handle async queries. DevNexus 2022
 
Building Modular monliths that could scale to microservices (only if they nee...
Building Modular monliths that could scale to microservices (only if they nee...Building Modular monliths that could scale to microservices (only if they nee...
Building Modular monliths that could scale to microservices (only if they nee...
 
Building modular monoliths that could scale to microservices (only if they ne...
Building modular monoliths that could scale to microservices (only if they ne...Building modular monoliths that could scale to microservices (only if they ne...
Building modular monoliths that could scale to microservices (only if they ne...
 
Leveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyLeveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results Asynchrhonously
 
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021Builiding Modular monoliths that can scale to microservices. JBCNConf 2021
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021
 
Cdm mil-18 - hypermedia ap is for headless platforms and data integration
Cdm mil-18 - hypermedia ap is for headless platforms and data integrationCdm mil-18 - hypermedia ap is for headless platforms and data integration
Cdm mil-18 - hypermedia ap is for headless platforms and data integration
 
What's in a community like Liferay's
What's in a community like Liferay'sWhat's in a community like Liferay's
What's in a community like Liferay's
 
Java9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadJava9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidad
 
Managing user's data with Spring Session
Managing user's data with Spring SessionManaging user's data with Spring Session
Managing user's data with Spring Session
 
Parallel streams in java 8
Parallel streams in java 8Parallel streams in java 8
Parallel streams in java 8
 
Construccion de proyectos con gradle
Construccion de proyectos con gradleConstruccion de proyectos con gradle
Construccion de proyectos con gradle
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.
 
Midiendo la calidad de código en WTF/Min (Revisado EUI Abril 2014)
Midiendo la calidad de código en WTF/Min (Revisado EUI Abril 2014)Midiendo la calidad de código en WTF/Min (Revisado EUI Abril 2014)
Midiendo la calidad de código en WTF/Min (Revisado EUI Abril 2014)
 
Measuring Code Quality in WTF/min.
Measuring Code Quality in WTF/min. Measuring Code Quality in WTF/min.
Measuring Code Quality in WTF/min.
 
Spring4 whats up doc?
Spring4 whats up doc?Spring4 whats up doc?
Spring4 whats up doc?
 
Gradle como alternativa a maven
Gradle como alternativa a mavenGradle como alternativa a maven
Gradle como alternativa a maven
 
El poder del creador de Software. Entre la ingeniería y la artesanía
El poder del creador de Software. Entre la ingeniería y la artesaníaEl poder del creador de Software. Entre la ingeniería y la artesanía
El poder del creador de Software. Entre la ingeniería y la artesanía
 
Geo-SentimentZ
Geo-SentimentZGeo-SentimentZ
Geo-SentimentZ
 
Wtf per lineofcode
Wtf per lineofcodeWtf per lineofcode
Wtf per lineofcode
 
A real systemwithjms-rest-protobuf-mongodb
A real systemwithjms-rest-protobuf-mongodbA real systemwithjms-rest-protobuf-mongodb
A real systemwithjms-rest-protobuf-mongodb
 

Kürzlich hochgeladen

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 

Kürzlich hochgeladen (20)

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 

HDTR images with Photoshop Javascript Scripting

  • 2. Dr Jeckyll & Mr Hide Haciendo Fotos desde los 16 años Exposiciones Colectivas e indivudales Ing. técnico en Informática de sistemas Sw Engineer & Trainer @dgomezg@d_v_g
  • 3. The HDTR technique Term coined by Martin Krzywinski HDTR High Dynamic Time Range
  • 4. The HDTR Technique Term coined by Martin KrzywinskiHDTR | High Dynamic Time Range http://mkweb.bcgsc.ca/fun/hdtr/
  • 6. The Planning Spot the place (Find out if its going to be crowded at sunset) Find out when and where the sun sets Check the weather forecast (A rainy sunset looks quite different)
  • 8. Photographic Shot Keep the camera steady for several hours (a TRIPOD will help) Set a NEUTRAL White Balace Keep a const Depth of Field (Aperture Priority) Better if you can shot Tethered to a Computer Pick some BEERS & FRIENDS (but pay attention to the camera)
  • 9. TOOLS and Setup Tethered Shooting Set Aperture Priority Set timered shooting (TIMELAPSE SHOOTING)
  • 12. The Photoshop Process Described at http://mkweb.bcgsc.ca/fun/hdtr/?tutorial
  • 14. Available AT http://mkweb.bcgsc.ca/fun/hdtr/?CODE Martin Krzywinski Implementation • Perl BASED • PROS • Easy setup & RUN • FREE • No dependencies (but Perl & libs) • CONS • Verbose blending config • No tuning posibility of result image
  • 15. PS Scripting alternative • PROS • Final image un PSD format with layers • You could further adjust the result • Easy config & run • CONS • PS License required • Harder to code
  • 17. Photoshop JS • Since PHOTOSHOP CS 1 (experimental support in PS 7.0 via an optional plugin) • Cross platform • New DOM To access most of Photoshop features and properties
  • 18. Photoshop’s DOM • BUT Still some operations not available: Gradients, Adjustment Layers, Layer Effects, polygonal selections....
  • 19. Access to the “Hidden” functionality • JS Classes from original PS SDK interface • ActionDescriptor, • ActionList • ActionReference • Use codes as parameters
  • 20. Access to the “Hidden” functionality ScriptListener plugin //-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ var  V1  =  new  ActionDescriptor(); var  V2  =  new  ActionDescriptor(); V2.putUnitDouble(charIDToTypeID("Hrzn"),charIDToTypeID("#Pxl"),  345);   V2.putUnitDouble(charIDToTypeID("Vrtc"),charIDToTypeID("#Pxl"),  667); V1.putObject(charIDToTypeID("From"),charIDToTypeID("Pnt  "),  V2); var  V3  =  new  ActionDescriptor(); [...] Records User’s interaction to JS script var fillWithGradient = function(startX, startY, endX, endY) { var V1 = new ActionDescriptor(); var V2 = new ActionDescriptor(); V2.putUnitDouble( charIDToTypeID("Hrzn"), charIDToTypeID("#Pxl"), startX); // start point X V2.putUnitDouble( charIDToTypeID("Vrtc"), charIDToTypeID("#Pxl"), startY); // start point Y V1.putObject( charIDToTypeID("From"), charIDToTypeID("Pnt "), V2); var V3 = new ActionDescriptor();
  • 21. Access to the “Hidden” functionality Code translation //-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ var  V1  =  new  ActionDescriptor(); var  V2  =  new  ActionDescriptor(); V2.putUnitDouble(charIDToTypeID("Hrzn"),charIDToTypeID("#Pxl"),  345);   V2.putUnitDouble(charIDToTypeID("Vrtc"),charIDToTypeID("#Pxl"),  667); V1.putObject(charIDToTypeID("From"),charIDToTypeID("Pnt  "),  V2); var  V3  =  new  ActionDescriptor(); [...] Translating codes /* lMID.maskHides = 1214529900;//"HdAl" lMID.maskRevealsAll = 1383492673;//"RvlA" lMID.maskReveals = 1383492691;//"Rvls" lMID.mask = 1299409696;//"Msk " lMID.at = 1098129440;//"At " lMID.using = 1433628263;//"Usng" lMID.userMask = 1433629261;//"UsrM" lMID.make = 1298866208;//"Mk " lMID.property = 1349677170;//"Prpr" ... */ cTID = function(s) { return app.charIDToTypeID(s); }; sTID = function(s) { return app.stringIDToTypeID(s); };
  • 22. Photoshop Extended Script • SOME Photoshop classes are defined in an extended an particular way alert(app.activeDocument.height); #include  "modules/json/json.js" alert(JSON.stringify(app.activeDocument.height));
  • 23. Photoshop ExtendScript .JSX .JS Convention ExtendScript files Regular files not using special Adobe classes and functions
  • 25. DEVELOPMENT TOOLS ExtendScript Toolkit • Delivered with every Creative Suite product • Need to set the target application • Combo • #target • Benefits • run on application • Debug tools • Inspector
  • 26. DEVELOPMENT TOOLS Any other JS editor Launch script via File > Scripts > Browse ...
  • 28. Process config var  hdtrConfig  =  {        direction  :  Direction.VERTICAL        ,  maskOffset  :  25        ,  guideSpacing  :  function  ()  {                if  (this.direction  ==  Direction.VERTICAL)  {                        return  this.docDimensions.width  /  this.shots;                }  else  {                        return  this.docDimensions.height  /  this.shots;                }        } }; Added later: - Image (document) dimensions - Number of original shots - Blending Offset (in Pixels)
  • 29. Source file selection & further config var files = app.openDialog(); hdtrConfig.shots = files.length; hdtrConfig.docDimensions = getImageFileDimensions(files[0]); hdtrConfig.offset = hdtrConfig.maskOffset * hdtrConfig.guideSpacing(); var getImageFileDimensions = function(file) { var imageDocument = app.open(file); var documentDimensions = { "height" : document.height, "width" : document.width, "resolution" : document.resolution}; imageDocument.close(); return documentDimensions; }
  • 30. HDTR document var  hdtrDocument  =  app.documents.add( hdtrConfig.docDimensions.width,   hdtrConfig.docDimensions.height, hdtrConfig.docDimensions.resolution); drawGuides(hdtrDocument,  hdtrConfig.direction,  hdtrConfig.shots); var  drawGuides  =  function(document,  direction,  number)  {   var  distance  =  (direction  ==  Direction.HORIZONTAL)? document.height  /  number  : document.width  /  number  ;   for  (var  i  =  0;  i  <  number  +  1;  i++)  {     var  position;     position  =  i  *  distance;     document.guides.add(direction,   new  UnitValue(position,  position));   } }
  • 31. Main Loop var  refGuide; var  from; var  to; for  (index  =  0;  index  <  files.length;  index++)  {        addLayerFromFile(hdtrDocument,  files[index]);        if  (index  >  0)  {                refGuide  =  hdtrDocument.guides[index];                from  =  refGuide.coordinate  -­‐  hdtrConfig.offset;                to  =  refGuide.coordinate  +  hdtrConfig.offset;                createLayerMask(hdtrDocument,  hdtrDocument.activeLayer,  false);                fillWithGradient(from,  hdtrConfig.docDimensions.height  /2,                                to,  hdtrConfig.docDimensions.height  /2);        } }
  • 32. Add Layer from File var  addLayerFromFile  =  function(hdtrDocument,  file)  {        var  sourceDocument  =  app.open(file);        app.activeDocument  =  sourceDocument;        app.activeDocument.activeLayer.copy();        app.activeDocument  =  hdtrDocument;        hdtrDocument.paste();        hdtrDocument.activeLayer.name  =   (hdtrDocument.artLayers.length  -­‐1)  +  "-­‐"  +  sourceDocument.name;        sourceDocument.close(); }
  • 33. Create Layer Mask var  createLayerMask  =  function(doc,  layer,  fromSelection)  {        var  desc  =  new  ActionDescriptor();        desc.putClass(cTID("Nw    "),  cTID("Chnl"));                var  ref  =  new  ActionReference();        ref.putEnumerated(cTID("Chnl"),  cTID("Chnl"),  cTID("Msk  "));        desc.putReference(cTID("At    "),  ref);                if  (fromSelection  ==  true)  {                desc.putEnumerated(cTID("Usng"),  cTID("UsrM"),  cTID("RvlS"));        }  else  {                desc.putEnumerated(cTID("Usng"),  cTID("UsrM"),  cTID("RvlA"));        }        executeAction(cTID("Mk    "),  desc,  DialogModes.NO); }
  • 34. Fill with Gradient var fillWithGradient = function(startX, startY, endX, endY) { var V1 = new ActionDescriptor(); var V2 = new ActionDescriptor(); V2.putUnitDouble( charIDToTypeID("Hrzn"), charIDToTypeID("#Pxl"), startX); // start point X V2.putUnitDouble( charIDToTypeID("Vrtc"), charIDToTypeID("#Pxl"), startY); // start point Y V1.putObject( charIDToTypeID("From"), charIDToTypeID("Pnt "), V2); var V3 = new ActionDescriptor(); .... Better to see the source code
  • 38. Easier configuration Using Photoshop UI Photoshop CS1 User Interaction via Alerts Photoshop CS2 Added ScriptUI (page 187 of PS CS2 JS Reference) Photoshop CS3+ ScriptUI moved to PS JS TOOLS GUIDE
  • 39. Script UI var  dlg  =  new  Window("dialog{text:'Script  Interface',bounds: [100,100,561,269], iwtfkhamhc:EditText{bounds:[16,16,444.95,94]  ,  text:'Your  text  goes   here'  ,properties:{multiline:false,noecho:false,readonly:false}}, button0:Button{bounds:[17,102,117,122]  ,  text:'Save'  }, button1:Button{bounds:[236,101,336,121]  ,  text:'Cancel'  }, button2:Button{bounds:[345,101,445,121]  ,  text:'Whatever'  }, slider0:Slider{bounds:[18,138,173,148]  ,  minvalue:0,maxvalue:100,value: 0}, checkbox0:Checkbox{bounds:[190,133,261,154]  ,  text:'Checkbox  Text'  }, dropdown0:DropDownList{bounds:[299,134,443,149],properties:{items: ['Select  One']}} };"); dlg.show();
  • 41. Q & A