Building an Image Search Plugin for Photoshop

How to add image search APIs into your UXP plugin.

Editor’s Note: This week’s guest post is by Ashikka, a Fullstack Developer Intern in the Major League Hacking Fellowship for the Fall 2021 cohort. Over the 12 week program, she worked on five issues in the Photoshop UXP samples repo, including developing an Unsplash Plugin Sample.

— Erin Finnegan, Community Engineer, Adobe Creative Cloud

︎Ashikka’s Unsplash plugin sample in action.

︎Ashikka’s Unsplash plugin sample in action.

This post is primarily written for plugin developers who have some experience with JavaScript and are familiar with the UXP platform and Adobe Photoshop.

It can be a hassle to import images to your Photoshop workspace. Wouldn’t it be easier to retrieve image search results and import images from the internet to your workspace without having to toggle between multiple windows and tabs?

Editor’s Note: In addition to Adobe Stock, several stock image search plugins are available from the Exchange Marketplace. Ashikka’s plugin sample demonstrates how to build your own stock image search tool.

This blog post will help you integrate different image search APIs into your UXP plugins. For the scope of this blog post, we will use the Unsplash API.

Start with the Starter Template

We will start building our plugin using this UXP starter template. This template is in JavaScript and uses the React framework. We will create a simple backend that interacts with the Unsplash API and returns results to the plugin UI.

Building the Backend

The backend is built in Node.js runtime environment using the express framework and the Unsplash API.

First, we will create a POST endpoint which does the following:

  1. Get the pictureName parameter from your request body.
  2. Create an API instance using the createAPI function and pass the accessKey and fetch as parameters.
  3. Search for the picture we are looking for using the getPhotos function and format the results according to our needs.

In the end, this is how our route will look:

https://gist.github.com/ashikka/a705ac9a34e9577ed5b5c5ef001c8acd#file-routes-js

On hitting the route with the pictureName parameter, we should get a response like this:

︎Response on hitting the route

︎Response on hitting the route

Integrating the Backend

Next, we will build UI for our plugin by creating a panel. As the name suggests, a panel is a dashboard for specific features in your plugin. So, for example, our panel named Unsplash.jsx will contain the main code for our use case.

To access any panel inside your plugin, you need to have an entry point that lets you interact with the PanelController.

https://gist.github.com/ashikka/2ae1053e10d028eb80235d79e77df618#file-index-jsx

We need to first create a controller for our panel named unsplashController, which uses the Unsplash component. This controller needs to define parameters like id and menuItems. Then, we need to make our panel an entry point for the plugin. We can do this using the EntryPoints API in UXP.

Great! Now, we can talk interact with our plugin. Let’s make a simple HelloWorld panel to test if everything is ok. Load the plugin’s manifest.json in the dist folder to UXP Developer Tool after building. It should look something like this:

︎The Hello World panel written in React.

︎The Hello World panel written in React.

Writing the plugin

Awesome! Now we will start working on the actual code for our plugin. We need to interact with the backend we created in the previous steps to make API calls. This can be achieved using axios.

https://gist.github.com/ashikka/9e99dd434671d0287dd507d82a9378d2#file-request-js

For the plugin’s UI, we need to do two things:

  1. Replicate an image search experience for the user within our panel.
  2. Display the results inside the plugin window.

We need to “preserve” the input text, and the search results between function calls to do these things. We can make use of the useState hook for the same.

https://gist.github.com/ashikka/5ed2ceb0e7b1a7daaf2122faa96c9481#file-Unsplash-jsx

In the above code snippet, we set the searchTerm state variable to the current value inside an input box and the searchResults variable to the results retrieved after making a POST request to our backend with the searchTerm inside the request body.

https://gist.github.com/ashikka/f5411e3470e3dc4f15d1ae5a956d5791#file-downloadIt-jsx

Fetching the Image

Once we have a link for the image selected by the user, the next step is to download the image, save it on the user’s desktop and open it as a layer. We accomplish this using our downloadIt function, which does the following:

  1. First, it uses fetch() API to download the image as binary data and converts it to an array of bits.
  2. Next, we use UXP’s getFileForSaving() method to display a prompt asking the user for the destination location to save the image.
  3. Finally, we detect if there is a document currently open on Photoshop and then load the image as a layer on the same.

https://gist.github.com/ashikka/60d1aacc9372417335bcf2c7db3484b9#file-plugin-html

Finally, we integrate the functions we’ve already created to our basic front end, and we’re good to go! We can now build our plugin and reload it in the UXP Developer Tool.

That’s all, folks!

Voila! It works! You can integrate as many image search APIs as you want into your plugin. I hope this has been useful.

null

I contributed this open-source sample to the Photoshop UXP documentation repo during my time as an MLH Fellow. You can also contribute to the repo if you’re interested. If you want to be an MLH Fellow, you may apply for the next cohort here.

You can play with the code for this sample plugin on Github. Photoshop v22.0.0 and the UXP Developer Tool are required to try it out.

Feel free to look at the code, learn from it, and consider contributing to the samples repo!

For more stories like this, subscribe to our Creative Cloud Developer Newsletter.