UNPKG

img-webpify

Version:

A modern and robust Node.js library for converting images to and from the WebP format. This library is a wrapper around Google's pre-compiled cwebp, dwebp, gwebp, and webpmux command-line utilities.

83 lines (73 loc) 3.85 kB
'use strict'; const fs = require('fs/promises'); // Use the modern promise-based fs API const path = require('path'); const { v4: uuid } = require('uuid'); const temp_path = require('./temp_path.js'); const webp = require('./webpconverter.js'); /** * Core conversion function that handles in-memory data by writing it to * temporary files, running cwebp, and cleaning up afterwards. * This is the single source of truth for the conversion logic. * * @param {Buffer} inputBuffer The image data to convert. * @param {string} imageType The file extension of the input image (e.g., 'png', 'jpg'). * @param {string} option The options string for the cwebp command (e.g., '-q 80'). * @param {string} [extra_path] Optional subdirectory within the temp directory. * @returns {Promise<Buffer>} A promise that resolves with the resulting WebP buffer. * @throws {Error} Throws if any step of the process fails. */ const convertToWebpBuffer = async (inputBuffer, imageType, option, extra_path) => { const filename = uuid(); const tempDir = temp_path(extra_path); const inputFilePath = path.join(tempDir, `${filename}.${imageType}`); const outputFilePath = path.join(tempDir, `${filename}.webp`); // The 'finally' block is crucial. It guarantees that we attempt to clean up // the temporary files, regardless of whether the 'try' block succeeds or fails. try { // 1. Write the input buffer to a temporary file. await fs.writeFile(inputFilePath, inputBuffer); // 2. Run the cwebp conversion process. Awaiting a promise-based function is clean. await webp.cwebp(inputFilePath, outputFilePath, option); // 3. Read the resulting WebP file back into a buffer. const outputBuffer = await fs.readFile(outputFilePath); // 4. Return the result. return outputBuffer; } catch (error) { // If an error occurs, log it and re-throw it to ensure the caller's promise rejects. console.error('WebP conversion failed:', error); throw error; } finally { // 5. Clean up both temporary files. // Use { force: true } to prevent errors if files were never created. await fs.rm(inputFilePath, { force: true }); await fs.rm(outputFilePath, { force: true }); } }; /** * Converts an image buffer to a WebP buffer. * @param {Buffer} buffer - The input image buffer. * @param {string} image_type - The file extension of the input image (e.g., 'png'). * @param {string} option - Options for the cwebp command (e.g., '-q 80'). * @param {string} [extra_path] - Optional subdirectory for temp files. * @returns {Promise<Buffer>} A promise that resolves with the WebP buffer. */ module.exports.buffer2webp = (buffer, image_type, option, extra_path) => { // Directly call the core function. No more inefficient conversions. return convertToWebpBuffer(buffer, image_type, option, extra_path); }; /** * Converts a base64 image string to a WebP base64 string. * @param {string} base64str - The input image as a base64 string. * @param {string} image_type - The file extension of the input image (e.g., 'png'). * @param {string} option - Options for the cwebp command (e.g., '-q 80'). * @param {string} [extra_path] - Optional subdirectory for temp files. * @returns {Promise<string>} A promise that resolves with the WebP image as a base64 string. */ module.exports.base64str2webp = async (base64str, image_type, option, extra_path) => { // First, convert the base64 string to a buffer. const inputBuffer = Buffer.from(base64str, 'base64'); // Then, use the same core conversion logic. const outputBuffer = await convertToWebpBuffer(inputBuffer, image_type, option, extra_path); // Finally, convert the resulting buffer back to a base64 string. return outputBuffer.toString('base64'); };