Automating Image Workflows
with APIs
who am i?
- Raymond Camden
- Senior Developer Evangelist for Adobe
- Husband, father of 8 kids, 5 cats, 1 dog, and no sleep
- Blog: raymondcamden.com
- Email: jedimaster@adobe.com
Adobe Photoshop API
- Image automation for Photoshop + Lightroom
- Set of REST APIs
- Node sample in development
- Photoshop experience not required! 😀
What's it cost?
- Free trial (500 API calls, no production use)
- SMB/Individual: 0.15 per call (subscribe via AWS)
- Enterprise: Reach out!
- Latest: Pricing
Current List of Features
- Photoshop Actions, Smart Object editing, Text layer editing, Smart Crop, Depth Blur, Rendering (PDF to JPG, thumbnails, etc), layer editing, resizing, artboard creation, remove background, and image mask
- AutoTone, AutoStraighten, Lightroom Presets and edits
Credentials
- Adobe ID
- No credit card/payment required
- Sign up
Checking Access - Part 1
- Convert client id + secret to Access Token...
- Using new OAuth Server-to-Server creds
- All can be done in one API call
CODE
Show generateAccessToken
Checking Access - Part 2
- Hit the "hello" endpoint
- This isn't *required*
Storage
- All services work with remote files only!
- AWS S3
- Google Drive
- Azure
- Dropbox
- Any readable URL (for input)
- Any writable URL (for output)
Storage
- All services work with remote files only!
- AWS S3
- Google Drive
- Azure
- Dropbox
- Any readable URL (for input)
- Any writable URL (for output)
API Flow
- Get the input URL (or URLs)
- Specify your output URL (or URLs)
- Create your JSON body
- Hit the endpoint
- Poll for response
- Repeat. Profit. Etc.
Example 1: Remove Background
{
"input": {
"href": "string",
"storage": "external"
},
"options": {
"optimize": "performance",
},
"output": {
"href": "string",
"storage": "external",
"overwrite": true,
"color": {
"space": "rgb"
},
"mask": {
"format": "soft"
}
}
}
API Ref
Polling
- Take the result from the job creation...
- Poll at an interval
- Wait for status 'succeeded' or 'failed'
CODE
Show removeBg_withPoll
ActionJSON
- New(ish)
- Takes an Action JSON file and applies to new images
- Like the Action endpoint, but flexible
- Enabling:
- Enable Developer Mode in Photoshop (via Preferences/Plugins)
- Plugins/Development - select
Record Action Commands
DEMO+CODE
Show creating the file in PS,
Show actionJSON example
CODE
Modify actionJSON example
Lightroom APIs
- AutoStraighten
- Presets
- Edit (exposure, contract, sharpness, many more)
- AutoTone (auto fix exposure, contract, sharpness, saturation, etc)
Real Use Case
- Marketing creates ad, with dummy text
- Day before sale, finally, folks agree on text
- You need to generate a final version...
- Oh, and in multiple languages
- An hour before they change the text 😀
Our Input:
Example 2: Edit Text Layer
{
"inputs": [{
"href": input,
"storage": "external"
}],
"options": {
"layers":[
{
"name":"Ad Copy",
"text":{
"content":text
}
}
]
},
"outputs": [{
"href": output,
"storage": "external",
"overwrite": true,
"type":"image/jpeg"
}]
};
API Ref
CODE
// Sample Lambda code, SDK still in development
const awsLib = require('/opt/nodejs/src/lib/awsLib')
const sdk = require('/opt/nodejs/config/config')
exports.handler = async (event) => {
try {
const client = await sdk.initSDK()
const input = {
// href: await awsLib.getSignedUrl('getObject', 'input/input01.jpg'), //ex: AWS S3 (s3://<awsConfig.bucketName>/input/input01.jpg)
href: 'https://raw.githubusercontent.com/adobe/adobe-photoshop-api-sdk/main/testfiles/input/input01.jpg',
storage: sdk.psApiLib.Storage.EXTERNAL,
}
const output = {
href: await awsLib.getSignedUrl('putObject', 'output/test01.png'),
storage: sdk.psApiLib.Storage.EXTERNAL,
type: sdk.psApiLib.MimeType.PNG
}
const job = await client.createCutout(input, output)
console.log(`Response: ${JSON.stringify(job,null,2)}\n`)
console.log(`Output File: ${await awsLib.getSignedUrl('getObject', 'output/test01.png')}\n`)
} catch (e) {
console.error(e)
}
};