How to Process and Resize Images in Bulk
Automatically resize, convert, and compress product images or uploaded files using the Image Tools connector.
What This Integration Does
Product catalogues, marketing portals, and user-generated content systems all generate piles of inconsistently-sized images that need cleaning up before they're useful - product photos resized to a standard aspect ratio for a storefront, hero images compressed for the web, thumbnails generated for previews, formats converted to WebP for faster loads. Doing this by hand or in a separate image microservice is painful; doing it inside a Spojit workflow keeps the whole pipeline (fetch, process, upload, notify) in one place.
The image connector handles each operation as a discrete tool - resize, crop, convert, compress, thumbnail, rotate, flip, grayscale, blur, and get-info for inspection. Each tool takes image bytes (typically as Base64 or fetched in-flight) and returns processed bytes you can pass to the next step or upload anywhere.
Prerequisites
- A source of images - product images from shopify, woocommerce, or bigcommerce; files from an ftp server; or uploads coming in via webhook.
- A destination to write processed images back to - the same e-commerce platform, an FTP bucket, or wherever your CDN reads from.
- An idea of the target dimensions and quality for each output (e.g. 2000px wide for hero, 800px for product grid, 200px for thumbnail).
Step 1: Trigger the Workflow
Pick a trigger that matches your batching strategy. For an overnight bulk pass use a Schedule trigger that fires once a day. For on-upload processing use a Webhook trigger fed by your storefront's product-image-created event. For a one-off migration use a Manual trigger with a list of image URLs in the input.
Step 2: Fetch the List of Images
Add a Connector node to enumerate what needs processing. For Shopify, shopify list-products returns each product with its image URLs nested. For an FTP bulk, use ftp list-directory to walk the folder. Project to just the URL list with a Transform node so the next step has clean input.
Step 3: Loop Over Each Image
Wrap the per-image work in a Loop node configured as ForEach over the URL list. Inside the loop, fetch the image bytes with http http-get (most platforms return image URLs you have to GET separately). The response body is the raw image; it's passed to the image tools as Base64 between steps. For very large batches, run the loop with a parallelism setting greater than 1 to overlap I/O and CPU - 4 to 8 concurrent iterations is a reasonable starting point.
Step 4: Inspect and Decide
Call image get-info first to read the current dimensions, format, and size. Follow it with a Condition node that skips images already within tolerance - reprocessing identical images wastes CPU and risks degrading quality on repeated compress passes. Example check: {{ step.info.width }} <= 2000 && {{ step.info.format }} === "webp".
Step 5: Resize, Convert, and Compress
Chain the actual transformations. A typical pipeline:
- image
resizewith target width 2000px, fit modecontain, preserving aspect ratio. - image
convertto WebP (or AVIF if your storefront supports it) for smaller file sizes at the same visual quality. - image
compresswith quality 80 - high enough to be visually clean, low enough to roughly halve the file size against the default. - Optionally, image
thumbnailin parallel to produce a 200px preview alongside the main asset.
For multiple output sizes from one source, fan out with a Parallel node - one branch per output size - rather than redoing the resize sequentially.
Step 6: Upload and Notify
Send each processed image back to its destination. For Shopify, that's shopify update-product with the new image attached. For FTP, ftp upload-file into the right folder. After the loop completes, post a summary to slack send-message with counts of images processed, skipped, and failed so the team knows the batch landed. Track per-image failures by inserting failed records into a mongodb collection via insert-documents for replay.
Tips
- Run the most expensive step (compress) last - resizing first means compress works on a smaller image and runs faster.
- For format conversion to WebP, expect 25 to 35 percent smaller files than equivalent-quality JPEG with no visible loss.
- Image data is passed as Base64 between steps - keep an eye on workflow memory if you're processing thousands of large images.
- Use Parallel branching when generating multiple sizes from a single source; use Loop concurrency when iterating over a list of images.
Common Pitfalls
- EXIF orientation - photos from phones often carry orientation metadata. A resize without honouring orientation can produce sideways images. Call image
rotateusing the EXIF angle (or strip and re-apply orientation) before resize. - Repeated lossy passes - re-running the compress step on already-compressed images gradually wrecks quality. The
get-info+ Condition check upfront prevents this. - Storefront file-size limits - some platforms reject uploads over a certain size or non-standard formats. Validate against their constraints before upload.
- Alpha channel loss - converting PNGs with transparency to JPEG drops the alpha and replaces it with black. Convert to WebP instead, which preserves transparency.
Testing
Pick three test images that cover the typical inputs you'll see - a large hero, a small product shot, and one with transparency or unusual aspect ratio - and run the workflow on just those via a Manual trigger. Inspect the outputs in the execution log (Spojit renders image previews) and verify dimensions, format, and visual quality before pointing the trigger at the full catalogue.