Convert Figma logo to code with AI

jwagner logosmartcrop.js

Content aware image cropping

12,827
580
12,827
21

Top Related Projects

Simple raster image tracer and vectorizer written in JavaScript.

28,864

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.

13,761

An image processing library written entirely in JavaScript for Node, with zero external or native dependencies.

6,946

GraphicsMagick for node

3,739

Resize image in browser with high quality and high speed

Pure Javascript OCR for more than 100 Languages 📖🎉🖥

Quick Overview

smartcrop.js is a JavaScript library that implements content-aware image cropping. It analyzes the visual content of an image to find the most interesting areas and then determines the best crop based on this analysis. This library is particularly useful for generating thumbnails or resizing images while preserving the most important visual elements.

Pros

  • Intelligent cropping that focuses on the most important parts of an image
  • Works with various image formats and sizes
  • Can be used both in the browser and with Node.js
  • Customizable options for fine-tuning the cropping algorithm

Cons

  • May not always produce perfect results for all types of images
  • Can be computationally intensive for large images or high volumes of processing
  • Requires additional setup for server-side usage
  • Limited documentation for advanced use cases

Code Examples

  1. Basic usage in the browser:
smartcrop.crop(image, { width: 100, height: 100 }).then(function(result) {
  console.log(result);
});

This code crops an image to 100x100 pixels, focusing on the most important area.

  1. Using with canvas in the browser:
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
smartcrop.crop(image, { width: 100, height: 100, canvas: canvas }).then(function(result) {
  var crop = result.topCrop;
  ctx.drawImage(image, crop.x, crop.y, crop.width, crop.height, 0, 0, 100, 100);
});

This example crops an image and draws the result onto a canvas element.

  1. Using with Node.js:
const smartcrop = require('smartcrop');
const sharp = require('sharp');

sharp('input.jpg')
  .raw()
  .toBuffer((err, buffer, { width, height }) => {
    smartcrop.crop(buffer, { width, height, width: 100, height: 100 }).then(result => {
      console.log(result);
    });
  });

This code demonstrates how to use smartcrop.js with Node.js and the sharp library for image processing.

Getting Started

To use smartcrop.js in your project, follow these steps:

  1. Install the library:

    npm install smartcrop
    
  2. Import the library in your JavaScript file:

    import smartcrop from 'smartcrop';
    
  3. Use the crop function to analyze and crop an image:

    const image = document.getElementById('myImage');
    smartcrop.crop(image, { width: 200, height: 200 }).then(result => {
      console.log(result.topCrop);
      // Use the result to crop your image
    });
    

For more advanced usage and options, refer to the project's documentation on GitHub.

Competitor Comparisons

Simple raster image tracer and vectorizer written in JavaScript.

Pros of ImageTracerJS

  • Focuses on vector image tracing, converting raster images to SVG
  • Supports multiple color quantization and layering options
  • Provides a command-line interface for easy integration into workflows

Cons of ImageTracerJS

  • Limited to image tracing functionality, not suitable for content-aware cropping
  • May produce larger file sizes for complex images due to vector conversion
  • Requires more processing time for detailed images compared to raster-based operations

Code Comparison

ImageTracerJS:

ImageTracer.imageToSVG(
  'image.jpg',
  function(svgstr) { console.log(svgstr); },
  { numberofcolors: 16, mincolorratio: 0 }
);

SmartCrop.js:

smartcrop.crop(image, { width: 100, height: 100 }).then(function(result) {
  console.log(result);
});

Summary

ImageTracerJS and SmartCrop.js serve different purposes in image processing. ImageTracerJS specializes in converting raster images to vector SVGs, offering various options for color quantization and layering. It's useful for creating scalable graphics but may result in larger file sizes for complex images. SmartCrop.js, on the other hand, focuses on content-aware image cropping, which is more suitable for generating thumbnails or focusing on important parts of an image. The choice between these libraries depends on the specific image processing needs of your project.

28,864

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.

Pros of Sharp

  • Broader image processing capabilities, including resizing, format conversion, and various transformations
  • High performance due to use of libvips library, making it suitable for large-scale image processing
  • Extensive documentation and active community support

Cons of Sharp

  • Larger package size and more dependencies
  • Steeper learning curve for basic operations compared to Smartcrop.js
  • Requires compilation of native modules, which can be challenging in some environments

Code Comparison

Sharp:

const sharp = require('sharp');

sharp('input.jpg')
  .resize(300, 300, { fit: 'cover' })
  .toFile('output.jpg');

Smartcrop.js:

const smartcrop = require('smartcrop');

smartcrop.crop(image, { width: 300, height: 300 })
  .then(result => console.log(result));

While Sharp offers a more comprehensive set of image processing tools, Smartcrop.js focuses specifically on intelligent cropping. Sharp's code is more straightforward for basic resizing, but Smartcrop.js provides a simpler API for content-aware cropping. Sharp is better suited for projects requiring extensive image manipulation, while Smartcrop.js excels in scenarios where intelligent cropping is the primary need.

13,761

An image processing library written entirely in JavaScript for Node, with zero external or native dependencies.

Pros of Jimp

  • More comprehensive image processing library with a wide range of features
  • Supports various image formats and operations (resize, crop, rotate, etc.)
  • Active development and community support

Cons of Jimp

  • Larger library size, which may impact load times and performance
  • May be overkill for simple cropping tasks
  • Lacks specialized content-aware cropping algorithms

Code Comparison

Jimp (basic crop):

Jimp.read('image.jpg')
  .then(image => {
    return image.crop(x, y, width, height).write('output.jpg');
  })
  .catch(err => {
    console.error(err);
  });

SmartCrop.js:

smartcrop.crop(image, { width: 100, height: 100 }).then(function(result) {
  console.log(result);
});

Summary

Jimp is a more comprehensive image processing library with a wide range of features, while SmartCrop.js focuses specifically on content-aware image cropping. Jimp offers broader functionality but may be excessive for simple cropping tasks. SmartCrop.js provides a specialized solution for intelligent cropping but lacks the extensive image manipulation capabilities of Jimp. The choice between the two depends on the specific requirements of your project and the level of image processing functionality needed.

6,946

GraphicsMagick for node

Pros of gm

  • Broader image manipulation capabilities, including resizing, rotating, and applying filters
  • Supports a wide range of image formats
  • Integrates with GraphicsMagick and ImageMagick, providing powerful image processing tools

Cons of gm

  • Requires external dependencies (GraphicsMagick or ImageMagick)
  • More complex setup and configuration
  • Larger library size and potentially slower performance for simple tasks

Code Comparison

gm:

const gm = require('gm');

gm('input.jpg')
  .resize(300, 300)
  .write('output.jpg', function (err) {
    if (!err) console.log('Image resized');
  });

smartcrop.js:

const smartcrop = require('smartcrop');

smartcrop.crop(image, { width: 300, height: 300 }).then(function(result) {
  console.log(result);
});

While gm offers a wide range of image manipulation functions, smartcrop.js focuses specifically on intelligent cropping. gm provides more general-purpose image processing capabilities, whereas smartcrop.js excels at automatically finding the best crop for a given image. The choice between the two depends on the specific requirements of your project and the complexity of image processing tasks you need to perform.

3,739

Resize image in browser with high quality and high speed

Pros of pica

  • Focuses on high-quality image resizing with various resampling algorithms
  • Supports both browser and Node.js environments
  • Offers better performance for large image resizing tasks

Cons of pica

  • Limited to resizing functionality, lacks intelligent cropping features
  • May require additional processing for complex image manipulations
  • Less suitable for content-aware image processing tasks

Code Comparison

pica:

const pica = require('pica')();

pica.resize(from, to, {
  unsharpAmount: 80,
  unsharpRadius: 0.6,
  unsharpThreshold: 2
})
.then(result => console.log('Resize done!'));

smartcrop.js:

const smartcrop = require('smartcrop');

smartcrop.crop(image, { width: 100, height: 100 })
  .then(function(result) {
    console.log(result);
  });

Key Differences

  • pica focuses on high-quality resizing, while smartcrop.js specializes in content-aware cropping
  • pica offers more control over resizing algorithms and quality, whereas smartcrop.js aims for intelligent crop selection
  • smartcrop.js is more suitable for generating thumbnails or focusing on important image areas, while pica excels in preserving image quality during resizing

Both libraries serve different purposes and can be complementary in image processing workflows, depending on the specific requirements of the project.

Pure Javascript OCR for more than 100 Languages 📖🎉🖥

Pros of Tesseract.js

  • Optical Character Recognition (OCR) capabilities for extracting text from images
  • Supports multiple languages and can recognize various types of text
  • Provides a comprehensive solution for text recognition tasks

Cons of Tesseract.js

  • Larger file size and potentially slower performance due to its extensive features
  • May require more setup and configuration for specific use cases
  • Not specifically designed for image cropping or content-aware resizing

Code Comparison

Smartcrop.js:

smartcrop.crop(image, { width: 100, height: 100 }).then(function(result) {
  console.log(result);
});

Tesseract.js:

Tesseract.recognize(image, 'eng')
  .then(({ data: { text } }) => {
    console.log(text);
  });

Summary

Smartcrop.js focuses on intelligent image cropping, while Tesseract.js specializes in OCR. Smartcrop.js is more lightweight and specific to image manipulation, whereas Tesseract.js offers powerful text recognition capabilities but may be overkill for simple image processing tasks. The choice between the two depends on whether the primary goal is image cropping or text extraction from images.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

smartcrop.js

example workflow

Smartcrop.js implements an algorithm to find good crops for images. It can be used in the browser, in node or via a CLI.

Example Image: https://www.flickr.com/photos/endogamia/5682480447/ by Leon F. Cabeiro (N. Feans), licensed under CC-BY-2.0

Note I'm currently working on a more advanced version of smartcrop.js based on machine learning. As part of that I'm looking for a large dataset of manually cropped images. If you know of such a dataset, please let me know.

Demos

Simple Example

// you pass in an image as well as the width & height of the crop you
// want to optimize.
smartcrop.crop(image, { width: 100, height: 100 }).then(function(result) {
  console.log(result);
});

Output:

// smartcrop will output you its best guess for a crop
// you can now use this data to crop the image.
{topCrop: {x: 300, y: 200, height: 200, width: 200}}

Download/ Installation

npm install smartcrop or just download smartcrop.js from the git repository.

Smarcrop requires support for Promises, use a polyfill for unsupported browsers or set smartcrop.Promise to your favorite promise implementation (I recommend bluebird).

Consider avoiding crops using dont-crop

If you are interested in using smartcrop.js to crop your images you should also consider to avoid cropping them by using dont-crop. Dont-crop gives you matching gradients and colors to pad and complement your images.

Example

Command Line Interface

The smartcrop-cli offers command line interface to smartcrop.js.

Node

You can use smartcrop from nodejs via either smartcrop-gm (which is using image magick via gm) or smartcrop-sharp (which is using libvips via sharp). The smartcrop-cli can be used as an example of using smartcrop from node.

Stability

While smartcrop.js is a small personal project it is currently being used on high traffic production sites. It has a basic set of automated tests and a test coverage of close to 100%. The tests run in all modern browsers thanks to saucelabs. If in any doubt the code is short enough to perform a quick review yourself.

Algorithm Overview

Smartcrop.js works using fairly dumb image processing. In short:

  1. Find edges using laplace
  2. Find regions with a color like skin
  3. Find regions high in saturation
  4. Boost regions as specified by options (for example detected faces)
  5. Generate a set of candidate crops using a sliding window
  6. Rank them using an importance function to focus the detail in the center and avoid it in the edges.
  7. Output the candidate crop with the highest rank

Face detection

The smartcrop algorithm itself is designed to be simple, relatively fast, small and generic.

In many cases it does make sense to add face detection to it to ensure faces get the priority they deserve.

There are multiple javascript libraries which can be easily integrated into smartcrop.js.

You can experiment with all of these in the smartcrop.js testbed

On the client side I would recommend using tracking.js because it's small and simple. Opencv.js is compiled from c++ and very heavy (~7.6MB of javascript + 900kb of data). jquery.facedetection has dependency on jquery and from my limited experience seems to perform worse than the others.

On the server side node-opencv can be quicker but comes with some annoying issues as well.

It's also worth noting that all of these libraries are based on the now dated viola-jones object detection framework. It would be interesting to see how more state of the art techniques could be implemented in browser friendly javascript.

Supported Module Formats

  • CommonJS
  • AMD
  • global export / window

Supported Browsers

See caniuse.com/canvas. A polyfill for Promises is recommended if you need to support old browsers.

API

smartcrop.crop(image, options)

Find the best crop for image using options.

image: anything ctx.drawImage() accepts, usually HTMLImageElement, HTMLCanvasElement or HTMLVideoElement.

Keep in mind that origin policies apply to the image source. You may not use cross-domain images without CORS clearance.

options: cropOptions

returns: A promise for a cropResult.

cropOptions

minScale: minimal scale of the crop rect, set to 1.0 to prevent smaller than necessary crops (lowers the risk of chopping things off).

width: width of the crop you want to use.

height: height of the crop you want to use.

boost: optional array of regions whose 'interestingness' you want to boost (for example faces). See boost;

ruleOfThirds: optional boolean if set to false it will turn off the rule of thirds composition weight.

debug (internal): if true, cropResults will contain a debugCanvas and the complete results array.

There are many more (for now undocumented) options available. Check the source and be advised that they might change in the future.

cropResult

Result of the promise returned by smartcrop.crop.

{
  topCrop: crop;
}

crop

An individual crop.

{
  x: 11, // pixels from the left side
  y: 20, // pixels from the top
  width: 1, // pixels
  height: 1 // pixels
}

boost

Describes a region to boost. A usage example of this is to take into account faces in the image. See smartcrop-cli for an example on how to integrate face detection.

{
  x: 11, // pixels from the left side
  y: 20, // pixels from the top
  width: 32, // pixels
  height: 32, // pixels
  weight: 1 // in the range [0, 1]
}

Note that the impact the boost has is proportional to it's weight and area.

Tests

You can run the tests using grunt test. Alternatively you can also just run grunt (the default task) and open http://localhost:8000/test/.

Benchmark

There are benchmarks for both the browser (test/benchmark.html) and node (node test/benchmark-node.js [requires node-canvas]) both powered by benchmark.js.

If you just want some rough numbers: It takes < 20 ms to find a square crop of a 640x427px picture on an i7. In other words, it's fine to run it on one image, it's suboptimal to run it on an entire gallery on page load.

Contributors

Ports, Alternatives

Version history

2.0.5

Fix TS1046: Top-level declarations in .d.ts files must start with either a 'declare' or 'export' modifier..

2.0.4

Typescript type definitions.

2.0.2

In short: It's a lot faster when calculating bigger crops. The quality of the crops should be comparable but the results are going to be different so this will be a major release.

1.1.1

Removed useless files from npm package.

1.1

Creating github releases. Added options.input which is getting passed along to iop.open.

1.0

Refactoring/cleanup to make it easier to use with node.js (dropping the node-canvas dependency) and enable support for boosts which can be used to do face detection. This is a 1.0 in the semantic meaning (denoting backwards incompatible API changes). It does not denote a finished product.

License

Copyright (c) 2018 Jonas Wagner, licensed under the MIT License (enclosed)

NPM DownloadsLast 30 Days