Working with Images: resize, crop in TypeScript

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Working with Images in TypeScript: Resize and Crop

In modern web development, client-side image processing is a common task. TypeScript, thanks to its strict typing and integration with modern browser APIs, allows you to perform resize and crop operations safely and efficiently. In this article, we will cover two approaches: using the native Canvas API and working with server-side libraries sharp and jimp for Node.js.



1. Canvas API: Client-Side Processing Without Dependencies

The browser's HTMLCanvasElement is the easiest way to manipulate images. It requires no additional packages and works in any modern browser.



1.1. Resizing via Canvas

The main idea is to draw the source image onto a canvas with new dimensions, then export the result.

function resizeImage(  source: HTMLImageElement,  targetWidth: number,  targetHeight: number): Promise<Blob> {  return new Promise((resolve, reject) => {    const canvas = document.createElement('canvas');    canvas.width = targetWidth;    canvas.height = targetHeight;    const ctx = canvas.getContext('2d');    if (!ctx) {      reject(new Error('Canvas context not supported'));      return;    }    // Draw the image with new dimensions    ctx.drawImage(source, 0, 0, targetWidth, targetHeight);    // Export to Blob (default format is PNG)    canvas.toBlob((blob) => {      if (blob) resolve(blob);      else reject(new Error('Failed to create blob'));    }, 'image/jpeg', 0.9); // you can specify format and quality  });}

Important: When upscaling an image, quality may degrade — canvas uses bilinear interpolation. This is acceptable for previews, but not for printing.



1.2. Cropping with Coordinates

Cropping requires specifying a rectangular area of the source image.

function cropImage(  source: HTMLImageElement,  x: number,  y: number,  width: number,  height: number): Promise<Blob> {  return new Promise((resolve, reject) => {    const canvas = document.createElement('canvas');    canvas.width = width;    canvas.height = height;    const ctx = canvas.getContext('2d');    if (!ctx) {      reject(new Error('Canvas not supported'));      return;    }    // Extract a fragment from the source image    ctx.drawImage(source, x, y, width, height, 0, 0, width, height);    canvas.toBlob((blob) => {      if (blob) resolve(blob);      else reject(new Error('Blob creation failed'));    }, 'image/png');  });}

Tip: Always check that the coordinates x, y, width, height do not exceed the boundaries of the source image, otherwise the canvas will return empty areas.



2. Server-Side Processing: sharp and jimp

If you are working in a Node.js and TypeScript environment, the libraries sharp (C++ native, high performance) and jimp (pure JS, cross-platform) are standard solutions.



2.1. Installation and Import

// Installation// npm install sharp// npm install jimp

import sharp from 'sharp';import Jimp from 'jimp';


2.2. Resizing with sharp

async function resizeWithSharp(  inputPath: string,  outputPath: string,  width: number,  height: number): Promise<void> {  await sharp(inputPath)    .resize(width, height, {      fit: 'cover',      // 'cover' - crops excess, 'contain' - fits within      position: 'center' // anchor point for cropping    })    .toFile(outputPath);}

The fit parameter defines the fitting strategy:

  • cover —

Recommendations