Compress Images w/ Airtable Script [Snippet] <> No-Code Supply Co.

Compress Images w/ Airtable Script

Compress Images w/ Airtable Script
// Define settings fields and descriptions
const config = input.config({
title: "Compress Images",
description: "Check and compress an image in each record of a view using the [Kraken.io API](https://kraken.io/docs/getting-started). Script created by [Base Scripts](https://nocodesupply.co/basescripts) — use at your own discretion.",
items: [
input.config.text("krakenAPIKey", {
label: "Kraken API Key",
description: "Sign up for a Kraken account, and get your key from the Account > API Credentials page.",
}),
input.config.text("krakenAPISecret", {
label: "Kraken API Secret",
description: "Sign up for a Kraken account, and get your secret from the Account > API Credentials page.",
}),
input.config.text("minImageSize", {
label: "Minimum Image Size (kb)",
description: "When an image is checked, if its current file size is above this value then it will get compressed, if its below it will remain as is.",
}),
input.config.text("imageResizeWidth", {
label: "Resize Image Width",
description: "When an image is compressed, what is the width it should be resized too?",
}),
input.config.select("imageOrientation", {
label: "Rezied Image Orientation",
description: "When the image is compressed, what orientation should it retain?",
options: [
{ label: "Landscape", value: "landscape" },
{ label: "Portrait", value: "portrait" },
],
}),
input.config.select("convertWebp", {
label: "Convert Image to WebP?",
description: "When the image is compressed, do you want it also converted to a Webp file type?",
options: [
{ label: "True", value: "true" },
{ label: "False", value: "false" },
],
}),
input.config.table("tableSelect", {
label: "Table",
description: "Select the table where the images should be checked and compressed.",
}),
input.config.view("viewSelect", {
label: "View",
description: "Select the view where the images should be checked and compressed.",
parentTable: "tableSelect",
}),
input.config.field("imageSelect", {
label: "Image Field",
description: "Select the attachment field where the image to check and compress is currently stored.",
parentTable: "tableSelect",
}),
input.config.field("imageSizeSelect", {
label: "Image Size Field",
description: "Select the text field where the size of the image should be output.",
parentTable: "tableSelect",
}),
input.config.field("imageTypeSelect", {
label: "Image Type Field",
description: "Select the text field where the file type of the image should be output.",
parentTable: "tableSelect",
}),
input.config.field("imageErrorSelect", {
label: "Image Error Field",
description: "Select the checkbox field that gets checked if there is any error when trying to compress the image.",
parentTable: "tableSelect",
}),
],
});
// Set config choices to variables
const configAPIKey = config.krakenAPIKey;
const configAPISecret = config.krakenAPISecret;
const configMinSize = parseInt(config.minImageSize, 10); // Convert to number
const configImageResize = parseInt(config.imageResizeWidth, 10); // Convert to number
const configImageOrientation = config.imageOrientation;
const configConvertWebp = config.convertWebp === "true"; // Convert string to boolean
const configTable = config.tableSelect.name;
const configView = config.viewSelect.name;
const configImage = config["imageSelect"].name;
const configImageSize = config["imageSizeSelect"].name;
const configImageType = config["imageTypeSelect"].name;
const configImageError = config["imageErrorSelect"].name;
// Set table and view
const table = base.getTable(configTable);
const view = table.getView(configView);
// Loop through each image field to get size
let query = await view.selectRecordsAsync({ fields: [configImage, "Name"] });
for (let record of query.records) {
// Get image size
let imageSize = record.getCellValue(configImage)[0].size / 1000;
// Get image URL
let imageToResizeUrl = record.getCellValue(configImage)[0].url;
// Get image type
let imageType = record.getCellValue(configImage)[0].type;
// Get record name
let imageRecordName = record.getCellValue("Name");
if (imageSize >= configMinSize) {
// IF image size is over minimum size set then compress the image via API
let callToKraken = await remoteFetchAsync("https://api.kraken.io/v1/url", {
method: "POST",
body: JSON.stringify({
auth: {
api_key: configAPIKey,
api_secret: configAPISecret,
},
// "dev": true,
url: imageToResizeUrl,
wait: true,
lossy: true,
webp: configConvertWebp,
resize: [
{
id: "compressed",
strategy: configImageOrientation,
width: configImageResize,
},
],
}),
headers: {
"Content-type": "application/json",
Accept: "application/json",
},
});
let returnedImages = await callToKraken.json();
if (!callToKraken.ok) {
// IF Kraken throws an error message, then continue to compress the next image
console.error(callToKraken);
await table.updateRecordAsync(record, {
[configImageError]: true,
});
continue;
} else {
// IF successful update image and size fields
await table.updateRecordAsync(record, {
[configImage]: [{ url: returnedImages.results.compressed.kraked_url }],
[configImageSize]: returnedImages.results.compressed.kraked_size / 1000,
[configImageType]: "image/webp",
});
console.log("Compressed image to " + returnedImages.results.compressed.kraked_size / 1000 + "KB (" + imageRecordName + ")");
}
} else {
//IF image size that is under the minimum size set then just update image size field
await table.updateRecordAsync(record, {
[configImageSize]: imageSize,
[configImageType]: imageType,
});
}
}

Use the Airtable Scripting extension to run this script across all images in attachment fields of a specific view, in order to compress, convert and resize the images to desired specs using the Kraken image compression API.

This is an iteration on the script originally sourced from here: https://www.nocodecollab.com/tutorial/airtable-scripts-to-resize-and-crop-images

Creators

Have feedback or a question related to this item? Drop us some feedback!

Curated: 
10.10.22

Similar items

Runway AI: Ambient Intelligence

7.30.24

Retronova

7.30.24

Renewed Vision

7.30.24

Public Work

7.30.24

Lobato

7.27.24

OVERLAY

7.25.24

Stewart & Partners

7.25.24

Jamm

7.25.24

Botanic Expo

7.25.24

SUPER GIANT

7.25.24

Defijn

7.25.24

Isle of Skye Whisky

7.25.24

Chrono

7.23.24

mmm

7.23.24

Jordan Gilroy

7.23.24

Templace

7.22.24

Brandfetch

7.22.24

The Magic of Clip Path

7.22.24

Codex

7.22.24

Rize

7.22.24

Le Flair Studios

7.17.24

Forms.Supply

7.16.24

Thind UI

7.15.24

CSS Hacks for Webflow

7.14.24

Christina Liubynska

7.14.24

Matteo Fabbiani

7.14.24
Load more

Bummer, no results

Try a different search/filter combo, or drop us some feedback if there is something missing you would love to see!

Reset filters

Subscribe for updates

Get updates on the latest curated resources and be the first to hear of new features.