As well as editing video at scale, Shotstack is also a versatile and powerful image editing API capable of automatically generating thousands of images in the cloud.
In this article we'll teach you how to compose and edit your first image using JSON and the Shotstack API as the first step to building automated image generation in to your applications and workflows.
Before you can complete this tutorial you will need the following:
If you don't have a developer account, please sign up first. There is a free to use developer sandbox and a free plan that will allow you to generate up to 100 images per month.
For this guide we'll be using cURL to POST JSON to our API endpoint so you will need some basic knowledge of interacting with APIs.
To validate your system has cURL installed, please type and run the command in your terminal or command prompt:
curl --version
Before generating an image using code, let's familiarize ourselves with some of the terminology and understand what is happening behind the scenes.
If you're familiar with our video editing features, you'll notice we use exactly the same configuration and parameters to assemble and compose our image. If you're new to our product, this guide will cover the basics of image editing but also a foundation for video editing.
An edit is the root level JSON object used to describe how assets like images or text are arranged to create an image. An edit includes a timeline and an output property.
A timeline contains all the elements of the image. These elements (also called assets) can be text titles, images, html, masks or a frame from a video. The assets are layered, arranged and positioned using tracks and clips.
A track is a layer that works the same way layers work in an application like Adobe Photoshop. A Track allows you to layer assets on top of each other or to group assets for complex compositions.
Assets are placed inside clips and positioned on the timeline inside tracks. In video editing you specify a start time and length when the clips will play but for image editing we can set the start time as 0 and a length of 1.
Assets are the individual elements that make up the image such as text, html and other images. Each asset has it's own set of parameters such as font size or source URL.
The output specifies the final render properties, such as the image format and size.
To start, we will create the simplest image possible, the "Hello World" of automated image editing.
Create a text file called hello.json
and paste the following contents:
{
"timeline": {
"background": "#000000",
"tracks": [
{
"clips": [
{
"asset": {
"type": "title",
"text": "Hello World",
"style": "future"
},
"start": 0,
"length": 1
}
]
}
]
},
"output": {
"format": "jpg",
"size": {
"width": 1000,
"height": 600
}
}
}
The JSON above describes a 1000px x 600px jpg image with a black background and a title asset with the words 'Hello World'. Note that we set a start and length even though these will be ignored by the editor and have no effect. These settings are typically used for video editing.
We can now post the file to the Shotstack API by running the command below. Be sure to replace the x-api-key
parameter with the developer key from your account
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d @hello.json \
https://api.shotstack.io/stage/render
The API should return a response like below:
{
"success": true,
"message": "Created",
"response": {
"message": "Render Successfully Queued",
"id": "8f5394c1-1c8d-4187-a0ff-74d565ac04f6"
}
}
Copy the id
field from the response as we'll use it for a new cURL request to retrieve the status of the render and the URL of the final image.
Run the following command, replacing 8f5394c1-1c8d-4187-a0ff-74d565ac04f6
with the id from the response you received:
curl -X GET \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
https://api.shotstack.io/stage/render/8f5394c1-1c8d-4187-a0ff-74d565ac04f6
Once the render is done, the status
in the response will change to done
and you will be able to see the URL to view the output image.
{
"success": true,
"message": "OK",
"response": {
"id": "8f5394c1-1c8d-4187-a0ff-74d565ac04f6",
"owner": "rodvzd13a2",
"plan": "sandbox",
"status": "done",
"error": "",
"duration": 1,
"billable": 1,
"renderTime": 516.92,
"url": "https://shotstack-api-stage-output.s3-ap-southeast-2.amazonaws.com/rodvzd13a2/8f5394c1-1c8d-4187-a0ff-74d565ac04f6.jpg",
"poster": null,
"thumbnail": null,
"data": {
"output": {...},
"timeline": {...}
},
"created": "2021-06-28T20:34:25.400Z",
"updated": "2021-06-28T20:34:27.270Z"
}
}
Congratulations! You generated your first image using the Shotstack API.
Let's return to the JSON file. To add some interest to the image we are going to add an actual photo of the world using this image we downloaded from Pexels: https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/images/earth.jpg
.
We want to display the image underneath the text, so we'll add a second track for the image asset and place it below the title asset to make sure the title is rendered on top of the background.
{
"timeline": {
"background": "#000000",
"tracks": [
{
"clips": [
{
"asset": {
"type": "title",
"text": "Hello World",
"style": "future"
},
"start": 0,
"length": 1
}
]
},
{
"clips": [
{
"asset": {
"type": "image",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/images/earth.jpg"
},
"start": 0,
"length": 1
}
]
}
]
},
"output": {
"format": "jpg",
"size": {
"width": 1000,
"height": 600
}
}
}
You can use the previous cURL commands to post the JSON file and retrieve the image status and URL, providing you with the following image:
Our image is still looking a bit boring and isn't well designed. The text and photo are just in their default position with no real attention to detail.
Let's first break down the Hello World
text into two separate lines of text, with different sized fonts. We will use the rule of thirds and place the text using the position: left
property, and add an offset
to each word so they are positioned one on top of the other.
We will also offset the photo of the world to the right so that the text stands out by itself.
Replace the JSON file contents with the following and POST it to the API:
{
"timeline": {
"background": "#000000",
"tracks": [
{
"clips": [
{
"asset": {
"type": "title",
"text": "Hello",
"style": "future",
"size": "x-small",
"position": "left",
"offset": {
"x": 0.3,
"y": 0.1
}
},
"start": 0,
"length": 1
},
{
"asset": {
"type": "title",
"text": "World",
"style": "future",
"size": "medium",
"position": "left",
"offset": {
"x": 0.3,
"y": -0.1
}
},
"start": 0,
"length": 1
}
]
},
{
"clips": [
{
"asset": {
"type": "image",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/images/earth.jpg"
},
"start": 0,
"length": 1,
"offset": {
"x": 0.4
}
}
]
}
]
},
"output": {
"format": "jpg",
"size": {
"width": 1000,
"height": 600
}
}
}
Our final image now looks much more appealing with a well designed layout.
Rendering an image typically takes one to two seconds and multiple images can be created concurrently, allowing you to create hundreds to thousands of images on the fly.
Use cases include personalized customer experiences, automatically generated images for social media and e-commerce catalogs and as a cloud based alternative to Photoshop Actions.
You should now have an understanding of how easy it is to generate images and how to use the Shotstack API for editing images.
The RESTful design of the API means that you can use any programming language you are familiar with (or one of our SDKs to start integrating automated image generation in to your media centric applications and workflows.
curl --request POST 'https://api.shotstack.io/v1/render' \
--header 'x-api-key: YOUR_API_KEY' \
--data-raw '{
"timeline": {
"tracks": [
{
"clips": [
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3.amazonaws.com/footage/beach-overhead.mp4"
},
"start": 0,
"length": "auto"
}
]
}
]
},
"output": {
"format": "mp4",
"size": {
"width": 1280,
"height": 720
}
}
}'