async resize(width, height, {
        resample = 2,
    } = {}) {

        // Do nothing if the image already has the desired size
        if (this.width === width && this.height === height) {
            return this;
        }

        // Ensure resample method is a string
        let resampleMethod = RESAMPLING_MAPPING[resample] ?? resample;

        // Calculate width / height to maintain aspect ratio, in the event that
        // the user passed a null value in.
        // This allows users to pass in something like `resize(320, null)` to
        // resize to 320 width, but maintain aspect ratio.
        const nullish_width = isNullishDimension(width);
        const nullish_height = isNullishDimension(height);
        if (nullish_width && nullish_height) {
            return this;
        } else if (nullish_width) {
            width = (height / this.height) * this.width;
        } else if (nullish_height) {
            height = (width / this.width) * this.height;
        }

        if (IS_BROWSER_OR_WEBWORKER) {
            // TODO use `resample` in browser environment

            // Store number of channels before resizing
            const numChannels = this.channels;

            // Create canvas object for this image
            const canvas = this.toCanvas();

            // Actually perform resizing using the canvas API
            const ctx = createCanvasFunction(width, height).getContext('2d');

            // Draw image to context, resizing in the process
            ctx.drawImage(canvas, 0, 0, width, height);

            // Create image from the resized data
            const resizedImage = new RawImage(ctx.getImageData(0, 0, width, height).data, width, height, 4);

            // Convert back so that image has the same number of channels as before
            return resizedImage.convert(numChannels);

        } else {
            // Create sharp image from raw data, and resize
            let img = this.toSharp();

            switch (resampleMethod) {
                case 'box':
                case 'hamming':
                    if (resampleMethod === 'box' || resampleMethod === 'hamming') {
                        console.warn(`Resampling method ${resampleMethod} is not yet supported. Using bilinear instead.`);
                        resampleMethod = 'bilinear';
                    }

                case 'nearest':
                case 'bilinear':
                case 'bicubic':
                    // Perform resizing using affine transform.
                    // This matches how the python Pillow library does it.
                    img = img.affine([width / this.width, 0, 0, height / this.height], {
                        interpolator: resampleMethod
                    });
                    break;

                case 'lanczos':
                    // https://github.com/python-pillow/Pillow/discussions/5519
                    // https://github.com/lovell/sharp/blob/main/docs/api-resize.md
                    img = img.resize({
                        width, height,
                        fit: 'fill',
                        kernel: 'lanczos3', // PIL Lanczos uses a kernel size of 3
                    });
                    break;

                default:
                    throw new Error(`Resampling method ${resampleMethod} is not supported.`);
            }

            return await loadImageFunction(img);
        }

    }
Resize the image to the given dimensions. This method uses the canvas API to perform the resizing.
@param {number} width The width of the new image. `null` or `-1` will preserve the aspect ratio.
@param {number} height The height of the new image. `null` or `-1` will preserve the aspect ratio.
@param {Object} options Additional options for resizing.
@param {0|1|2|3|4|5|string} [options.resample] The resampling method to use.
@returns {Promise<RawImage>} `this` to support chaining.