DEV Community

Cover image for Sharp Resizer: A CLI App For Resizing Images in Bulk
evanryan210
evanryan210

Posted on

Sharp Resizer: A CLI App For Resizing Images in Bulk

Intro

In this article, we will be building a command line interface (CLI) application to assist in creating copies of an image to any number of specified sizes. This tool can be super useful and save you a lot of time, especially when building mobile apps that require different image sizes to display in different parts of the app.


You can download the code through GitHub here: https://github.com/evanryan210/sharp-resize

Final result: A set of resized images in your folder ready to use!

Getting Started

For this CLI app we will need to install a few node packages. We will be using node package manager so make sure you have that installed at this point. If you do not have it installed you can download it here: https://nodejs.org/en/download. The commands to install the packages we will be using are listed below.

npm install sharp
npm install fs
npm install path
Enter fullscreen mode Exit fullscreen mode

Sharp: A high-speed Node.js module that converts large images to varying dimensions.
Fs: A module that allows you to work with the file system on your computer.
Path: The Path module provides a way of working with directories and file paths.

In our project folder, lets make a json file and name it resize.json. This is where we will store our path to the image we want to resize, our path to the destination we want to save our resized images to, and an array of our desired sizes.

{
    "imagePath" : "[IMAGE PATH TO BE RESIZED]",
    "outputPath": "[DESTINATION FOLDER PATH TO STORE IMAGES]",
    "settings": {
        "ios": [20,29,40,40,58,60,60,76,80,87,120,120,152,167,180,1024],
        "android": [36,48,64,72,96,144,192,512]
    }
}
Enter fullscreen mode Exit fullscreen mode

Note: You can add however many 'settings' values you need. For this example, I did two since I wanted two sets of resized images in their own respective folder.

Setting Up a Watcher

If you are not aware, since we are using Typescript we must compile our code before we run it in node. To avoid having to compile each time we make changes to our app, I prefer to run a watcher in the terminal to save some time. This watcher will look for changes in our file and compile instantly. The command to run the watcher is as follows:

tsc -w
Enter fullscreen mode Exit fullscreen mode

And your terminal should display something like this:

[5:05:25 PM] Starting compilation in watch mode...

[5:05:27 PM] Found 0 errors. Watching for file changes.
Enter fullscreen mode Exit fullscreen mode

(P.S. Make sure not to accidentally close this terminal)

Index.ts

Now we will be working in the root index.ts file of the project. Lets start by defining a 'type', PlatformData, for our json object we just created.

type PlatformData = {
    imagePath: string,
    outputPath: string,
    settings: Record<string, number[]>
}
Enter fullscreen mode Exit fullscreen mode

Now we are going to use the fs module we installed to get the data from our resize.json file using the fs.readFileSync() method.

const data = fs.readFileSync(path.join(`resize.json`), 'utf8');
const parsedData: PlatformData = JSON.parse(data);
const imgPath = parsedData.imagePath //"[IMAGE PATH]"
const folderPath = parsedData.outputPath //"[DESTINATION FOLDER PATH]"
Enter fullscreen mode Exit fullscreen mode

We are then going to parse that data and store it in a variable, parsedData. Now we can use this parsed data and also create imgPath and folderPath.

Now lets make the actual function that is going to take the image size and platform as arguments, and give us a file from the resized image data at the specified path.

const resize = (imgSize: number, platform: string) =>{
    sharp(imgPath)
        .resize(imgSize)
        .toFile(`${folderPath}/${platform}/sample_${imgSize}.jpg`, function (err) {
        });
}
Enter fullscreen mode Exit fullscreen mode

Now that our function to resize our image is done, lets make sure there is a directory to store our new set of resized images by checking if it exists using fs.existsSync(folderPath). If it does not exist, we can use fs.mkdirSync(folderPath) to create a folder as shown below.

if (!fs.existsSync(folderPath)){
    fs.mkdirSync(folderPath)
}
Enter fullscreen mode Exit fullscreen mode

Lastly, we need to do a try...catch that will use a forEach() loop to iterate through the values in our array(s) and resize the image to each size being passed. After this stage you have a completed resizing app!

try {
    const platforms = parsedData.settings
    Object.keys(platforms).forEach(platform => {
        if (!fs.existsSync(`${folderPath}/${platform}`)) {
            fs.mkdirSync(`${folderPath}/${platform}`)
            //Only if you want platform specific folders
        }
        const platformSizes = platforms[platform]
        platformSizes.forEach(size => {
            resize(size, platform)
        })
    })
    console.log(`Resizer has loaded images here: ${folderPath} `)
} catch (err) {
    console.error(err);
}
Enter fullscreen mode Exit fullscreen mode

Usage

To use the app we just created, make sure the resize.json has the proper values for imagePathand outputPath, and simply run the following command in the terminal.

node index
Enter fullscreen mode Exit fullscreen mode



I hoped you enjoyed this walkthrough! Best of luck in your coding endeavors :D

Author,
Evan Ryan, OrangeSpark Solutions

Top comments (0)