smartcrop.js README

The project's README from github.com/jwagner/smartcrop.js. As one markdown file: README.md.

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

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)

smartcrop.js (jwagner/smartcrop.js)

Searching Database…

这是什么?smartcrop.js 实现了一种算法,可以自动为图片找到合适的裁剪区域,因此你不必手动选择裁剪范围。
它是一个库还是完整的应用?它是一个小型 JavaScript 库,可以在浏览器中运行,也可以在 Node 中运行,或通过打包好的 CLI 使用。
我该如何把它添加到项目中?用 'npm install smartcrop' 安装即可,或者直接从 git 仓库下载 smartcrop.js 并引入。
在较旧的浏览器中运行还需要别的东西吗?它需要 Promise 支持,因此对于不支持的浏览器,你需要使用 Promise polyfill,或者将 smartcrop.Promise 设置为 bluebird 之类的库。
它开箱即用就能检测人脸吗?不能。核心算法只关注边缘、肤色和饱和度;人脸检测需要你使用单独的 JS 库自行添加,比如 tracking.js、opencv.js 或 ccv,并将结果作为 'boost' 区域传入。
处理大批量图片时表现如何?处理单张图片的速度足够快(在 i7 处理器上裁剪 640x427px 的图片不到 20ms),但它并不适合在页面加载时对整个图库运行。
这个裁剪算法究竟是如何决定保留哪些内容的?它通过拉普拉斯滤波找到边缘,检测类似肤色和高饱和度的区域,可选地对人脸等指定区域进行加权,用滑动窗口生成候选裁剪区域,然后用一个重要性函数对它们排序,该函数偏好中心区域的细节。
我能否在 Node 中使用 ImageMagick 或 libvips,而不是浏览器的 canvas?可以。smartcrop-gm 通过 gm 封装了 ImageMagick,smartcrop-sharp 通过 sharp 使用 libvips;smartcrop-cli 则演示了如何在 Node 中使用它。
有没有办法完全避免裁剪图片?有。相关项目 dont-crop 会用匹配的渐变或颜色填充图片,而不是裁剪它们。
有没有适用于其他语言的版本?有。已有的移植版本包括 smartcrop-java、smartcrop-android、smartcrop.go、smartcrop.py、一个 Ruby gem(smartcrop-rails),以及一个 C#/.NET 移植版(smartcrop.net)。
Creator
jwagner
Size
22.7 MB
Stars
13K
Age
12y
Commits · 90 Days