T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
1. Except where otherwise noted, this work is licensed
under: http://creativecommons.org/licenses/by-nc-sa/
3.0/
Uso del API Javascript
para obtener fotos HDTR
Leganés, 11 y 12 de febrero
David Gómez G.
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
@dgomezg @D_v_G
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)
@dgomezg @D_v_G
12. 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)
@dgomezg @D_v_G
13. TOOLS and Setup
Tethered Shooting
Set Aperture Priority
Set timered shooting
(TIMELAPSE SHOOTING)
@dgomezg @D_v_G
19. 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
@dgomezg @D_v_G
21. 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
@dgomezg @D_v_G
22. Photoshop’s DOM
• BUT Still some operations not
available: Gradients, Adjustment
Layers, Layer Effects, polygonal
selections....@dgomezg @D_v_G
23. Access to the “Hidden”
functionality
• JS Classes from original PS SDK
interface
• ActionDescriptor,
• ActionList
• ActionReference
• Use codes as parameters
@dgomezg @D_v_G
24. 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();
26. Photoshop Extended
Script
• SOME Photoshop classes are defined in
an extended and particular way
alert(app.activeDocument.height);
#include "modules/json/json.js"
alert(JSON.stringify(app.activeDocument.height));
29. 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
32. Process config
var hdtrConfig = {
direction : Direction.VERTICAL
, guidesOffset : 5
, 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 # of Columns)
33. 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;
}
34. 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));
}
}
35. 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);
}
}
@dgomezg @D_v_G
37. 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);
}
@dgomezg @D_v_G
38. 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