npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

scale-crop-rotate

v1.0.4

Published

Scale, crop and rotate images, not blocking UI.

Downloads

18

Readme

Scale, crop and rotate images, not blocking UI. :construction::collision:

import scaleCropRotate, { imageDataToDataURL, URLToImageData } from 'scale-crop-rotate';

const progress = document.getElementsByTagName('progress')[0];

const resizeImage = async (imageURL, width, height) => {
  try {
    const data = await URLToImageData(imageURL);
    const resultData = await scaleCropRotate(data, width, height)
      .progress(value => {
        progress.value = value;
      });
    
    const image = new Image;
    image.src = imageDataToDataURL(resultData);
    document.body.append(image);
  }
  catch(e) {
    console.error(e);
  }
}

resizeImage(
  '/assets/beautiful-landscape.jpg',
  384, 
  190
);

UI unblock

Image processing is an intensive CPU time consumption job. The data is processed in a very big loop inside the same Event loop iteration and, done in browser, may cause significant UI hickups. The solution may be to perform image processing in other thread with the help of the WebWorker. However it is possible to avoid blocking the UI thread by performing the work in range of many Event loop iterations.

This function reserves 10ms of every Event loop iteration to process data.

Performance

This function uses the technique, proposed by Paul Rouget in his article about pixel manipulation with Typed Arrays. His method reduces the number of read/write operations to the ArrayBuffer of the ImageData returned by the CanvasRenderingContext2D.getImageData() method. It saves the overall processing time when iterating through every pixel in the image.

The usage of Math is avoided in favour of Bitwise operators, giving a significant boost in performance in some browsers.

To save even more memory and time, scaling, cropping and rotating operations are performed in scope of the same loop.

Install

npm i scale-crop-rotate

or

yarn add scale-crop-rotate

Syntax

scaleCropRotate(source[, width, height[, cropX, cropY, cropWidth, cropHeight[, rotate[, enableSyncMode]]]]);
scaleCropRotate(source[, width, height[, rotate[, enableSyncMode]]]);
scaleCropRotate(source[, cropX, cropY, cropWidth, cropHeight[, rotate[, enableSyncMode]]]);
scaleCropRotate(source[, rotate[, enableSyncMode]]);

Parameters

source

The source image data, should be an instance of the ImageData.

width

A Number indicating width of the resulting image. If the value is 0, the width is adapted to keep the same aspect ratio as in the source image.

height

A Number indicating height of the resulting image. If the value is 0, the height is adapted to keep the same aspect ratio as in the source image.

cropX

A Number indicating distance from the left side of the source image to draw into the destination context. This allows to crop the source image from the left side. The default value is calculated to position the cropping area in center of the source image.

cropY

A Number indicating distance from the top side of the source image to draw into the destination context. This allows to crop the source image from the top side. The default value is calculated to position the cropping area in center of the source image.

cropWidth

A Number indicating the width of the area that will be transfered from the source image to the destination image. The default value is calculated to position the cropping area in center of the source image.

cropHeight

A Number indicating the height of the area that will be transfered from the source image to the destination image. The default value is calculated to position the cropping area in center of the source image.

rotate

A Number representing the Exif Orientation Tag, or a DOMString containig one of predefined rotation values: 90deg, 180deg, 270deg, horizontal, vertical. Last two predefined values allow to mirror image horizontally and vertically.

enableSyncMode

A Boolean switch forces function to work in syncronous mode. In this case funcion overall execution time is faster, but it blocks the UI.

Return values

Async mode

A Promise that resolves with an ImageData containing the resulting image. A Promise is extended with the .progress() method that recieves a function as an argument to handle the image processing progress.

Sync mode

An ImageData containing the resulting image.

Helper functions

To retrieve an ImageData out of different conventional data sources, use these functions:

blobToImageData

Retrieves an ImageData from a Blob object.

Syntax

scaleCropRotate.blobToImageData(object);

Parameters

object

A Blob object to retrieve an ImageData from.

Return value

A Promise that resolves with an ImageData.

imageDataToBlob

Converts an ImageData to a Blob object.

Syntax

scaleCropRotate.imageDataToBlob(object);

Parameters

object

An ImageData object to convert to a Blob object.

Return value

A Promise that resolves with a Blob object.

imageDataToDataURL

Converts an ImageData to a data URI string.

Syntax

scaleCropRotate.imageDataToDataURL(object);

Parameters

object

An ImageData object to convert to a data URI.

Return value

A DOMString containing the processed data URI.

imageToImageData

Retrieves an ImageData from HTMLImageElement object.

Syntax

scaleCropRotate.imageToImageData(object);

Parameters

object

An HTMLImageElement object to retrieve an ImageData from.

Return value

A Promise that resolves with an ImageData.

URLToImageData

Loads an image from the given URI and retrieves an ImageData.

Syntax

scaleCropRotate.URLToImageData(URIString);

Parameters

URIString

A DOMString containing the URI linking to the image to retrieve an ImageData from.

Return value

A Promise that resolves with an ImageData.

Other libraries

Check other great libraries to do in-browser image resizing:

License

MIT