Successfully reported this slideshow.
HDTR images withPhotoShopJavascript
Dr Jeckyll & Mr HideHaciendo Fotosdesde los 16 añosExposicionesColectivas e indivudalesIng. técnico enInformática de siste...
The HDTR techniqueTerm coined by Martin KrzywinskiHDTRHigh DynamicTime Range
The HDTR TechniqueTerm coined by Martin KrzywinskiHDTR | High DynamicTime Rangehttp://mkweb.bcgsc.ca/fun/hdtr/
StepsSHOTProcessPlan
The PlanningSpot the place(Find out if its going tobe crowded at sunset)Find outwhen and wherethe sun setsCheck theweather...
When and Wherethe sun sets
Photographic ShotKeep the camera steadyfor several hours(a TRIPOD will help)Set aNEUTRAL White BalaceKeep a const Depth of...
TOOLS and SetupTethered ShootingSet Aperture PrioritySet timered shooting(TIMELAPSE SHOOTING)
RESULTSRESULTS
Construction of aHDTR image
The Photoshop ProcessDescribed athttp://mkweb.bcgsc.ca/fun/hdtr/?tutorial
Automate theprocess
Available AThttp://mkweb.bcgsc.ca/fun/hdtr/?CODEMartin KrzywinskiImplementation• Perl BASED• PROS• Easy setup &RUN• FREE• ...
PS Scriptingalternative• PROS• Final image unPSD format withlayers• You couldfurther adjustthe result• Easy config & run• ...
PS scripting languages
Photoshop JS• Since PHOTOSHOP CS 1(experimental support in PS 7.0 via an optionalplugin)• Cross platform• New DOM To acces...
Photoshop’s DOM• BUT Still some operations notavailable: Gradients, AdjustmentLayers, Layer Effects, polygonalselections....
Access to the “Hidden”functionality• JS Classes from original PS SDKinterface• ActionDescriptor,• ActionList• ActionRefere...
Access to the “Hidden” functionalityScriptListener plugin//-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐...
Access to the “Hidden” functionalityCode translation//-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­...
Photoshop ExtendedScript• SOME Photoshop classes are defined inan extended an particular wayalert(app.activeDocument.heigh...
PhotoshopExtendScript.JSX .JSConventionExtendScript files Regular filesnot using special Adobeclasses and functions
DEVELOPMENT TOOLSExtendScript Toolkit
DEVELOPMENT TOOLSExtendScript Toolkit• Delivered with every Creative Suiteproduct• Need to set the target application• Com...
DEVELOPMENT TOOLSAny other JS editorLaunch script via File > Scripts > Browse ...
the PhotoshopHDTR.jsx script
Process configvar	  hdtrConfig	  =	  {	  	  	  	  direction	  :	  Direction.VERTICAL	  	  	  	  ,	  maskOffset	  :	  25	  ...
Source file selection& further configvar files = app.openDialog();hdtrConfig.shots = files.length;hdtrConfig.docDimensions...
HDTR documentvar	  hdtrDocument	  =	  app.documents.add(hdtrConfig.docDimensions.width,	  hdtrConfig.docDimensions.height,...
Main Loopvar	  refGuide;var	  from;var	  to;for	  (index	  =	  0;	  index	  <	  files.length;	  index++)	  {	  	  	  	  ad...
Add Layer from Filevar	  addLayerFromFile	  =	  function(hdtrDocument,	  file)	  {	  	  	  	  var	  sourceDocument	  =	  a...
Create Layer Maskvar	  createLayerMask	  =	  function(doc,	  layer,	  fromSelection)	  {	  	  	  	  var	  desc	  =	  new	 ...
Fill with Gradientvar fillWithGradient = function(startX, startY, endX, endY) {var V1 = new ActionDescriptor();var V2 = ne...
DEMO TIME!
Next Steps
Heterogeneous slicedistribution
Easier configurationUsing Photoshop UIPhotoshop CS1User Interaction via AlertsPhotoshop CS2Added ScriptUI(page 187 of PS C...
Script UIvar	  dlg	  =	  new	  Window("dialog{text:Script	  Interface,bounds:[100,100,561,269],iwtfkhamhc:EditText{bounds:...
Further Referencehttp://kcy.me/l7uohttp://kcy.me/l7ur
Q & A
Thanks@d_v_g@dgomezghttps://github.com/dgomezg/hdtr-photoshop-js
Upcoming SlideShare
Loading in …5
×

HDTR images with Photoshop Javascript Scripting

1,419 views

Published on

The process of creating HDTR images from the photographic shot to the processing via a Photoshop JS script explained.

This is the slide I used for my talk at the monthly MadridJS meeting held on May, 23rd 2013.

Published in: Technology, Art & Photos
  • Be the first to comment

HDTR images with Photoshop Javascript Scripting

  1. 1. HDTR images withPhotoShopJavascript
  2. 2. Dr Jeckyll & Mr HideHaciendo Fotosdesde los 16 añosExposicionesColectivas e indivudalesIng. técnico enInformática de sistemasSw Engineer & Trainer@dgomezg@d_v_g
  3. 3. The HDTR techniqueTerm coined by Martin KrzywinskiHDTRHigh DynamicTime Range
  4. 4. The HDTR TechniqueTerm coined by Martin KrzywinskiHDTR | High DynamicTime Rangehttp://mkweb.bcgsc.ca/fun/hdtr/
  5. 5. StepsSHOTProcessPlan
  6. 6. The PlanningSpot the place(Find out if its going tobe crowded at sunset)Find outwhen and wherethe sun setsCheck theweather forecast(A rainy sunset looksquite different)
  7. 7. When and Wherethe sun sets
  8. 8. Photographic ShotKeep the camera steadyfor several hours(a TRIPOD will help)Set aNEUTRAL White BalaceKeep a const Depth ofField (Aperture Priority)Better if you can shotTethered to a ComputerPick some BEERS & FRIENDS(but pay attention to the camera)
  9. 9. TOOLS and SetupTethered ShootingSet Aperture PrioritySet timered shooting(TIMELAPSE SHOOTING)
  10. 10. RESULTSRESULTS
  11. 11. Construction of aHDTR image
  12. 12. The Photoshop ProcessDescribed athttp://mkweb.bcgsc.ca/fun/hdtr/?tutorial
  13. 13. Automate theprocess
  14. 14. Available AThttp://mkweb.bcgsc.ca/fun/hdtr/?CODEMartin KrzywinskiImplementation• Perl BASED• PROS• Easy setup &RUN• FREE• No dependencies(but Perl & libs)• CONS• Verboseblendingconfig• No tuningposibility ofresult image
  15. 15. PS Scriptingalternative• PROS• Final image unPSD format withlayers• You couldfurther adjustthe result• Easy config & run• CONS• PS Licenserequired• Harder to code
  16. 16. PS scripting languages
  17. 17. Photoshop JS• Since PHOTOSHOP CS 1(experimental support in PS 7.0 via an optionalplugin)• Cross platform• New DOM To access most of Photoshopfeatures and properties
  18. 18. Photoshop’s DOM• BUT Still some operations notavailable: Gradients, AdjustmentLayers, Layer Effects, polygonalselections....
  19. 19. Access to the “Hidden”functionality• JS Classes from original PS SDKinterface• ActionDescriptor,• ActionList• ActionReference• Use codes as parameters
  20. 20. Access to the “Hidden” functionalityScriptListener 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 scriptvar fillWithGradient = function(startX, startY, endX, endY) {var V1 = new ActionDescriptor();var V2 = new ActionDescriptor();V2.putUnitDouble(charIDToTypeID("Hrzn"),charIDToTypeID("#Pxl"),startX); // start point XV2.putUnitDouble(charIDToTypeID("Vrtc"),charIDToTypeID("#Pxl"),startY); // start point YV1.putObject(charIDToTypeID("From"),charIDToTypeID("Pnt "), V2);var V3 = new ActionDescriptor();
  21. 21. Access to the “Hidden” functionalityCode 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. 22. Photoshop ExtendedScript• SOME Photoshop classes are defined inan extended an particular wayalert(app.activeDocument.height);#include  "modules/json/json.js"alert(JSON.stringify(app.activeDocument.height));
  23. 23. PhotoshopExtendScript.JSX .JSConventionExtendScript files Regular filesnot using special Adobeclasses and functions
  24. 24. DEVELOPMENT TOOLSExtendScript Toolkit
  25. 25. DEVELOPMENT TOOLSExtendScript Toolkit• Delivered with every Creative Suiteproduct• Need to set the target application• Combo• #target• Benefits• run on application• Debug tools• Inspector
  26. 26. DEVELOPMENT TOOLSAny other JS editorLaunch script via File > Scripts > Browse ...
  27. 27. the PhotoshopHDTR.jsx script
  28. 28. Process configvar  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. 29. Source file selection& further configvar 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. 30. HDTR documentvar  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. 31. Main Loopvar  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. 32. Add Layer from Filevar  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. 33. Create Layer Maskvar  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. 34. Fill with Gradientvar fillWithGradient = function(startX, startY, endX, endY) {var V1 = new ActionDescriptor();var V2 = new ActionDescriptor();V2.putUnitDouble(charIDToTypeID("Hrzn"),charIDToTypeID("#Pxl"),startX); // start point XV2.putUnitDouble(charIDToTypeID("Vrtc"),charIDToTypeID("#Pxl"),startY); // start point YV1.putObject(charIDToTypeID("From"),charIDToTypeID("Pnt "), V2);var V3 = new ActionDescriptor();....Better to see the source code
  35. 35. DEMO TIME!
  36. 36. Next Steps
  37. 37. Heterogeneous slicedistribution
  38. 38. Easier configurationUsing Photoshop UIPhotoshop CS1User Interaction via AlertsPhotoshop CS2Added ScriptUI(page 187 of PS CS2 JS Reference)Photoshop CS3+ScriptUI moved to PS JS TOOLS GUIDE
  39. 39. Script UIvar  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();
  40. 40. Further Referencehttp://kcy.me/l7uohttp://kcy.me/l7ur
  41. 41. Q & A
  42. 42. Thanks@d_v_g@dgomezghttps://github.com/dgomezg/hdtr-photoshop-js

×