We utilize the WebP format for images on our blog for better performance and accelerated load times. During the publishing process, a quick Google search typically leads me to various generic image conversion tools for format adjustments as needed. While some of these tools are effective, I was curious whether I could build an image conversion tool using ToolJet. I wanted something to handle image conversion, quality reduction, and file renaming all at once.

Thanks to ToolJet's compatibility with JavaScript, Python, and custom React components, I felt confident in its capacity to manage projects beyond the capabilities of standard internal tools. The process of bringing any application to life is expectedly straightforward in ToolJet, yet I was struck by the speed at which the image conversion tool came together. This inspired me to share the process that I followed with others who may be considering the creation of similar applications using low-code platforms.

Here's a glimpse of the final application:


If you wish to follow along this guide, sign up for ToolJet's free cloud account and begin by creating a new application named Image Converter.

Step One - Designing the UI

The first step of the development process is to create a basic UI.

  • Drag and drop a Container component from the components library on the right; rename it to header and adjust its size as shown in the reference image below.
  • Click on the Container component to reveal the properties panel on the right with Properties and Styles tabs.
  • In the Styles tab, change the Background color property by entering the hex code #152A65.
  • Drag and drop an Image component on the left corner of the Container, rename it to logo and fill in the following URL in its URL property: https://app.tooljet.com/logo.svg
  • Drag and drop a Text component on the right corner of the Container and name it headerText.
  • Enter ToolJet Image Converter under the Text property of the Text component, and adjust its Font weight and Text size properties to make it bold and increase its size.

Naming the components comes in handy when we want to access the data related to them. It's always a best practice to name components based on their functionality.

Step One - Create The Header

File Upload and Image Preview

  • Below the header, place a File Picker component and an Image component side by side. Rename the File Picker to fileUploader and the Image component to imagePreview.
  • Adjust the Image component's size so that the user can see a clear preview before downloading a converted image.
  • For the Image component's URL property, enter the following link:
    'https://blog.tooljet.com/wp-content/uploads/2024/01/ToolJet-Year-In-Review.webp'.
    For now, this will be the placeholder for the Image component.

The fileUploader (File Picker) will be used to upload images while the imagePreview (Image) component will display the preview of the uploaded images.

Step Two - Add File Picker and Image

Settings and Download

  • Add two Text components for File name and Quality labels and set their Text color property to #152A65.
  • Besides the File name label, insert a Text Input component and rename it to newFileName.
  • Next to the Quality label, place a Number Input component and rename it to qualitySetting.
  • Set the Text Input's Default value property to Converted File. This will set the default name of the file in case a custom name is not needed.
  • For the Number Input component, adjust the Default value property to 0.8, Minimum value property to 0.1, and Maximum value property to 1.0.

Step 2.5 - Add Text Input and Number Input Fields For File Name and Quality

  • Under Quality, add a Radio Button component and rename it to selectFormat.
  • Update the Radio button's Text color property and Active color property to #152A65.
  • Set the Radio Button's Default value property to {{"jpeg"}}.
    For Options property, input {{["jpeg", "webp", "png"]}},
    and for Option labels property, {{["jpeg", "webp", "png"]}}.
  • Add a Button component at the bottom, rename it to downloadButton, change its Button text property to Download, and its Background color property to #152A65.

Step Three - Create the Settings and Download Button

Step Two - Creating a JavaScript Query for the Image Conversion Process

Time to create a JavaScript Query that handles the image conversion process.

  • Expand the Query Panel below. Click on + Add, choose Run JavaScript code, and rename the created query to convertAndDownload.
  • Paste the following code into the code editor:

function convertImageUsingBase64(base64Data = components.fileUploader.file[0].base64Data, filename = components.newFileName.value, quality = components.qualitySetting.value, outputFormat = "image/"+components.selectFormat.value) {
    
    // Validate the output format
    const validFormats = ['image/png', 'image/jpeg', 'image/webp'];
    if (!validFormats.includes(outputFormat)) {
        console.error(`Invalid output format. Acceptable formats are: ${validFormats.join(', ')}`);
        return;
    }

    // Decode the base64 string to a Blob object
    const base64String = base64Data.split(';base64,').pop();
    const byteCharacters = atob(base64String);
    const byteNumbers = new Array(byteCharacters.length);
    for (let i = 0; i < byteCharacters.length; i++) {
        byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    const blob = new Blob([byteArray], {type: outputFormat});
    const url = URL.createObjectURL(blob);

    // Create an Image object to load the blob URL
    const img = new Image();
    img.onload = function() {
        // Create a canvas with the same dimensions as the image
        const canvas = document.createElement('canvas');
        canvas.width = img.naturalWidth;
        canvas.height = img.naturalHeight;
        const ctx = canvas.getContext('2d');

        // Draw the image at its natural size
        ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight);

        // Convert the canvas content to the specified format with quality
        const compressedDataURL = canvas.toDataURL(outputFormat, quality);

        // Create a temporary link to initiate the download
        const link = document.createElement('a');
        link.href = compressedDataURL;
        link.download = filename + '.' + outputFormat.split('/')[1]; // Append file extension based on format
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);

        // Clean up by revoking the blob URL to free memory
        URL.revokeObjectURL(url);
    };
    // Set the source of the image to the blob URL
    img.src = url;
}

convertImageUsingBase64();

This JavaScript snippet will:
1. Accept the base64 data of the uploaded image in the fileUploader (File Picker) component.
2. Use the name in the newFileName (Text Input) component to rename the image.
3. Adjust its quality based on the number we enter in the qualitySetting (Number Input) component.
4. Convert its format based on the choice we make on the selectFormat (Radio Button) component.

Step Four - Add Convert And Download Query

For more details on base64 and the above JavaScript function, refer to this article.

Step Three - Linking it All Together

  • Select the Button component, navigate to Events in the properties panel, and click on + New event handler.
  • Pick On click as the Event, Run Query the Action, and choose convertAndDownload as the Query(the query created in the previous step).

This will ensure that the query we had created in the previous step runs every time we click on the button.

Step Five Add Event To The Download Button

Create An Image Preview

  • Select the Image component and add this code to its URL property:
    {{'data:image;base64,' + components.fileUploader.file[0].base64Data}}

This will ensure that every time an image is uploaded in the fileUploader(File Picker) component, the imagePreview (Image) component will display it.

Step Six - Image Preview and Download

The core functionality of our image converter tool is now ready. You can test it by uploading an image, changing its file name, quality and format, and then downloading it using the download button.

Step Four - Additional Steps

Add Disability Condition To The Download Button

  • Under the Download component's Styles tab, find the Disable property, click on fx, and input:
    {{!components.fileUploader.file[0]}}

This will disable the download button if no file is present in the fileUploader(File Picker) component.

Add A Placeholder Image

  • For the Image component's URL property, replace the existing code with:
    {{components.fileUploader.file[0] ?
    'data:image;base64,' + components.fileUploader.file[0].base64Data : 'https://blog.tooljet.com/wp-content/uploads/2024/01/ToolJet-Year-In-Review.webp'; }}

This will check if a file is present in the fileUploader(File Picker) component and display a placeholder image in case it is not present.

The image converter is now complete and ready to launch. Simply click on the Promote button on the top-left, promote the application to the production environment, and release it.

Want to customize the application more?

  • Add more input fields to change the dimensions of the image. You can pass those dimensions to the JavaScript code and update the function to adjust the dimensions of the output file.
  • Add support for more output formats.
  • Create a pre-defined border for the output image.

Wondering what I should build next using ToolJet? A slack alternative? Or an AI Code Translator?