• This repository has been archived on 24/Jun/2019
  • Stars
    star
    442
  • Rank 98,271 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 12 years ago
  • Updated almost 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Node.js/AWS/ImageMagick-based image thumbnailing service.

Thumbd

Deprecation Warning: this project is no longer actively maintained and is left here as a historical artifact. Please feel free to fork this project and take over maintenance.

Coverage Status Build Status js-standard-style

Thumbd is an image thumbnailing server built on top of Node.js, SQS, S3, and ImageMagick.

You can easily run Thumbd on Heroku. Simply set the appropriate environment variables with config:set and deploy using the Procfile provided.

Note: Creating video thumbnails on Heroku requires use of custom ffmpeg buildpack. Please refer to Heroku deployment guide in Wiki.

Setup

apt-get install imagemagick
npm install thumbd

To install thumbd as a service:

npm install thumbd -g
thumbd install
thumbd start

Thumbd requires the following environment variables to be set:

  • AWS_KEY the key for your AWS account (the IAM user must have access to the appropriate SQS and S3 resources).
  • AWS_SECRET the AWS secret key.
  • BUCKET the bucket to download the original images from. The thumbnails will also be placed in this bucket.
  • AWS_REGION the AWS Region of the bucket. Defaults to: us-east-1.
  • CONVERT_COMMAND the ImageMagick convert command. Defaults to convert.
  • REQUEST_TIMEOUT how long to wait in milliseconds before aborting a remote request. Defaults to 15000.
  • S3_ACL the acl to set on the uploaded images. Must be one of private, or public-read. Defaults to private.
  • S3_STORAGE_CLASS the storage class for the uploaded images. Must be either STANDARD or REDUCED_REDUNDANCY. Defaults to STANDARD.
  • SQS_QUEUE the queue name to listen for image thumbnailing.

When running locally, I set these environment variables in a .env file and execute thumbd using Foreman.

Additionally, the following environment variable can be set to use a custom logger:

LOGGER_FILE the path to a javascript file that exports the info, warn and error methods.

Server

The thumbd server:

  • listens for thumbnailing jobs on the queue specified.
  • downloads the original image from our thumbnailng S3 bucket, or from an HTTP(s) resource.
    • HTTP resources are prefixed with http:// or https://.
    • S3 resources are a path to the image in the S3 bucket indicated by the BUCKET environment variable.
  • Uses ImageMagick to perform a set of transformations on the image.
  • uploads the thumbnails created back to S3, with the following naming convention: [original filename excluding extension]_[thumbnail suffix].[thumbnail format]

Assume that the following thumbnail job was received over SQS:

{
	"original": "example.png",
	"descriptions": [
		{
			"suffix": "tiny",
			"width": 48,
			"height": 48
		},
		{
			"suffix": "small",
			"width": 100,
			"height": 100,
			"background": "red"
		},
		{
			"suffix": "medium",
			"width": 150,
			"height": 150,
			"strategy": "bounded"
		}
	]
}

Once thumbd processes the job, the files stored in S3 will look something like this:

  • /example.png
  • /example_tiny.jpg
  • /example_small.jpg
  • /example_medium.jpg

Client

Submit thumbnailing jobs from your application by creating an instance of a thumbd client (contribute by submitting clients in other languages).

var Client = require('./thumbd').Client,
	client = new Client({
		awsKey: 'AWS-KEY',
		awsSecret: 'AWS-SECRET',
		awsRegion: 'AWS-REGION',
		sqsQueue: 'thumbnailing-queue',
		s3Bucket: 'thumbnails'
	});

var destination = '/example/awesome.jpg';

client.upload('/tmp/awesome.jpg', destination, function(err) {
	if (err) throw err;
	client.thumbnail(destination, [{suffix: 'small', width: 100, height: 100, background: 'red', strategy: 'matted'}], {
		notify: 'https://callback.example.com', // optional web-hook when processing is done.
		prefix: 'foobar' // optional prefix for thumbnails created.
	});
});

Thumbnailing options:

  • originalImagePaths: string or array, path to image or images that thumbnailing should be applied to.
  • thumbnailDescriptions: array describing the thumbnails that should be created.
  • opts: additional thumbnailing options.
    • notify: webhook to notify when thumbnailing is complete.
    • prefix: prefix for thumbnails created (defaults to original filename).
    • bucket: bucket to download image from (defaults to server's default bucket).
    • region: aws-region to download image from (defaults to server's default region).

Thumbnail Descriptions

The descriptions received in the thumbnail job describe the way in which thumbnails should be generated.

description accepts the following keys:

  • suffix: a suffix describing the thumbnail.
  • width: the width of the thumbnail.
  • height: the height of the thumbnail.
  • background: background color for matte.
  • format: what should the output format of the image be, e.g., jpg, gif, defaults to jpg.
  • strategy: indicate an approach for creating the thumbnail.
    • bounded (default): maintain aspect ratio, don't place image on matte.
    • matted: maintain aspect ratio, places image on width x height matte.
    • fill: both resizes and zooms into an image, filling the specified dimensions.
    • strict: resizes the image, filling the specified dimensions changing the aspect ratio
    • manual: allows for a custom convert command to be passed in:
      • %(command)s -border 0 %(localPaths[0])s %(convertedPath)s
  • quality: the quality of the thumbnail, in percent. e.g. 90.
  • autoOrient: true/false, whether to automatically rotate the photo based on EXIF data (for correcting orientation on phone images, etc)

CLI

Starting the server:

thumbd server --aws_key=<key> --aws_secret=<secret> --sqs_queue=<sqs queue name> --bucket=<s3 thumbnail bucket> [--aws_region=<region>] [--tmp_dir=</tmp>] [--s3_acl=<private or public-read>] [--s3_storage_class=<STANDARD or REDUCED_REDUNDANCY>]

Manually submitting an SQS thumbnailing job (useful for testing purposes):

thumbd thumbnail --remote_image=<path to image s3 or http> --descriptions=<path to thumbnail description JSON file> --aws_key=<key> --aws_secret=<secret> --sqs_queue=<sqs queue name> [--aws_region=<region>]
  • remote_image indicates the S3 object to perform the thumbnailing operations on.
  • thumbnail_descriptions the path to a JSON file describing the dimensions of the thumbnails that should be created (see example.json in the data directory).

Advanced Tips and Tricks

  • Creating a Mosaic: Rather than performing an operation on a single S3 resource, you can perform an operation on a set of S3 resources. A great example of this would be converting a set of images into a mosaic:
{
	"resources": [
		"images/image1.png",
		"images/image2.png"
	],
	"descriptions": [{
		"strategy": "%(command)s -border 0 -tile 2x1 -geometry 160x106 '%(localPaths[0])s' '%(localPaths[1])s' %(convertedPath)s",
		"command": "montage",
		"suffix": "stitch"
	}]
}

Creating Video Thumbnails on Heroku

Creating video thumbnails on Heroku requires using custom buildpack. In short :

  • install the ffmpeg custom buildpack.
  • use a custom strategy that utilizes ffmpeg for thumbnail generation, rather than convert.

For detailed instructions, please refer to Heroku deployment guide in Wiki.

The custom strategy can be used for a variety of purposes, experiment with it ℒ️

Production Notes

At Attachments.me, thumbd thumbnailed tens of thousands of images a day. There are a few things you should know about our production deployment:

Thumbd in Production

  • thumbd was not designed to be bullet-proof:
    • it is run with an Upstart script, which keeps the thumbnailing process on its feet.
  • Node.js is a single process, this does not take advantage of multi-processor environments.
    • we run an instance of thumbd per-CPU on our servers.
  • be mindful of the version of ImageMagick you are running:
    • make sure that you build it with the appropriate extensions for images you would like to support.
    • we've had issues with some versions of ImageMagick, we run 6.6.2-6 in production.
  • Your SQS settings are important:
    • setup a visibility-timeout/message-retention value that allows for a reasonable number of thumbnailing attempts.
    • we use long-polling to reduce the latency time before a message is read.
  • in production, thumbd runs on Node 0.8.x. It has not been thoroughly tested with Streams 2.

Projects Using Thumbd

If you build something cool using thumbd let me know, I will list it here.

  • Popbasic: designs limited edition, high quality clothing.
  • ineffable: A minimalist photo album powered by Flask and React.
  • s3-gif: Host your GIF collection on Heroku + Amazon S3.
  • talent-off: Online contest for sports videos.
  • attachments.me: created a searchable, visual, index of all of your email attachments (sadly defunct).

Copyright

Copyright (c) 2015 Contributors, See LICENSE.txt for further details.

More Repositories

1

c8

output coverage reports using Node.js' built in coverage
JavaScript
1,899
star
2

awesome-cross-platform-nodejs

πŸ‘¬ A curated list of awesome developer tools for writing cross-platform Node.js code
1,101
star
3

conventional-release-labels

Apply labels for automatically generated release notes, based on conventionalcommits.org
JavaScript
316
star
4

crapify

a proxy for simulating slow, spotty, HTTP connections
JavaScript
249
star
5

sandcastle

A simple and powerful sandbox for running untrusted JavaScript.
JavaScript
220
star
6

librarian-ansible

Port of librarian-chef, providing bundler functionality for Ansible roles.
Ruby
185
star
7

DoloresLabsTechTalk

Code for dolores labs tech talk.
JavaScript
176
star
8

which-cloud

given an ip address, return which cloud provider it belongs to (AWS, GCE, etc)
JavaScript
138
star
9

smtproutes

A simple, Sinatra inspired, SMTP routing server.
Python
137
star
10

secure-smtpd

Fork of Python's standard SMTP server. Adding support for various extensions to the protocol.
Python
128
star
11

wikifetch

Uses jQuery to return a structured JSON representation of a Wikipedia article.
JavaScript
126
star
12

karait

A ridiculously simple queuing system, with clients in various languages, built on top of MongoDB.
JavaScript
97
star
13

endtable

A ridiculously simple Object Mapper for Node running on top of CouchDB.
JavaScript
68
star
14

npm-tweets

Publishes tweets when libraries are updated on NPM.
JavaScript
64
star
15

routers-news

A crawler for various popular tech news sources. Read technology news from the comfort of your CLI.
JavaScript
56
star
16

unitgen

An API for building audio-unit-generators in Node.js
JavaScript
56
star
17

jDistiller

A page scraping DSL for extracting structured information from unstructured XHTML, built on Node.js and jQuery
JavaScript
49
star
18

top-npm-users

⭐ Generate a list of top npm users by based on monthly downloads.
JavaScript
46
star
19

travis-deploy-example

example of using Travis deployment to publish an npm module
JavaScript
40
star
20

onigurumajs

πŸ‘Ί a pure JavaScript port of the oniguruma regex engine
JavaScript
38
star
21

hl

πŸ‘– fancy pants syntax highlighting for the CLI
JavaScript
36
star
22

record-crate

index, organize, and search your music collection, DJ sick sets.
JavaScript
25
star
23

hide-secrets

for when you want to log an object but hide certain restricted fields, e.g., password
JavaScript
23
star
24

http2spy

test helpers for working with Node.js' http2 module
TypeScript
19
star
25

node-mocha-skeleton

A skeleton Node.JS project with Mocha for testing
JavaScript
18
star
26

puppeteer-to-istanbul-example

example of using puppeteer-to-istanbul to output istanbul reports from puppeteer coverage
JavaScript
17
star
27

nodemailer-mock-transport

mock-mailer for putting tests around services that use node-mailer
JavaScript
16
star
28

groundhogday

GroundhogDay lets you repeat an operation until you get it right.
Python
16
star
29

Adventures-in-Document-Thumbnailing

Some thoughts I have about creating thumbnails of common document types.
14
star
30

node-sexy-args

A sexy DSL for parsing the arguments passed into functions.
JavaScript
13
star
31

node-elasticsearch-proxy

A proxy to handle, and react to common error conditions raised by the elasticsearch http module.
JavaScript
10
star
32

mobius-js

MVC Web-Framework for JavaScript using Node.js and Express
JavaScript
10
star
33

renv

a command line interface for managing remote configuration, powered by etcd
JavaScript
10
star
34

toml-to-env

give me a toml configuration file, I'll give you export MY_ENV=foo
JavaScript
9
star
35

apidoc-md

Generate API documentation for your README from comments in your source-code
JavaScript
9
star
36

mongate

Client for Sleepy Mongoose that provides the same interface as Pymongo
Python
9
star
37

es2015-coverage

examples of minimal ES2015 projects, with testing and test coverage.
JavaScript
9
star
38

imaplib2

Fork of Piers Lauder's imaplib2 library for Python.
Python
9
star
39

dotgitignore

find the closest .gitignore file, parse it, and apply ignore rules
JavaScript
8
star
40

v8-coverage-merge

merges together two inspector-format coverage reports
JavaScript
7
star
41

elasticmapper

A damn simple mixin for integrating ActiveModel with ElasticSearch.
Ruby
7
star
42

AFHTTPRequestOperationManager-Timeout

Add timeout functionality to AFHTTPRequestOperationManager with Category
Objective-C
6
star
43

em-stretcher

EventMachine for Stretcher; a Fast, Elegant, ElasticSearch client
Ruby
6
star
44

any-path

:rage2: make the keys on an object path.sep agnostic.
JavaScript
5
star
45

gce-ips

fetch a list of Google Computer Engine's IP addresses using DNS lookup
JavaScript
5
star
46

webhooks

Elasticsearch WebHooks plugin.
Java
5
star
47

optional-dev-dependency

😎 try to install an optional development dependency, YOLO if you can't.
JavaScript
5
star
48

enronsearch

Perform searches on the Enron Email Dataset using ElasticSearch.
JavaScript
5
star
49

monkey-proxy

fork of tootallnate's proxy, adding hooks for modifying requests
JavaScript
4
star
50

istheshipstillstuck

is the ship still stuck?
JavaScript
4
star
51

nostrabot

The end of the world is nigh.
JavaScript
4
star
52

npm-typeahead

A tiny web-app that exposes typeahead search functionality for packages on http://www.npmjs.org.
JavaScript
4
star
53

path-buffer

Node.js' path module, but for buffers
JavaScript
3
star
54

mocoverage

a mocha reporter with coverage.
JavaScript
3
star
55

assertassert

:trollface: for when you can't decide on an assertion library
JavaScript
3
star
56

nanoleaf-travis

display Travis build statuses using nanoleaf aurora programmable lights: https://nanoleaf.me/en/
JavaScript
3
star
57

grpc-stress

stress tests for gRPC
JavaScript
3
star
58

private-module-heroku

example of using private modules on Heroku
JavaScript
3
star
59

node-coverage-debug

demonstrate issues we're bumping into instrumenting Node.js' test suite for coverage
HTML
3
star
60

leapiano

A midi piano built on top of the Leap Motion device.
JavaScript
3
star
61

example-redwood-blog

redwoodjs JAMstack framework on GCP
JavaScript
3
star
62

gh-commit-scan

scan commits in git repository
JavaScript
3
star
63

npme-auth-foo

Example of a foo npmE auth strategy.
JavaScript
3
star
64

yearincommits

GitHub 2014 commits leader board
JavaScript
3
star
65

soundcloud-backup

backup the meta information in your SoundCloud account (DJs you follow, tracks you've liked).
JavaScript
2
star
66

hackillinois-bot

experimenting with a yargs chat-bot for Hack Illinois
JavaScript
2
star
67

npm-coverage

An always-out-of-date ℒ️ coverage report for npm/npm.
HTML
2
star
68

plane-rpg

RPG I made en route from SFO to YYZ
JavaScript
2
star
69

jsdoc-region-tag

replace region tags with code samples
JavaScript
2
star
70

flaky.dev

track flaky tests over time, open issues on GitHub
JavaScript
2
star
71

citgm-harness

harness for running Canary in the Gold Mine builds
2
star
72

top-npm-users-server

server for top-npm-users addon
JavaScript
2
star
73

conventional-hud

Generate a CHANGELOG for GitHub repositories that follow conventionalcommits.org
JavaScript
2
star
74

node-micro-test

An asynchronous unit testing framework in under 40 lines of code.
1
star
75

leapdraw

Leapdraw allows you to Scribble on any website using the Leap Motion.
JavaScript
1
star
76

google-cloud-python

Testing changelog.json generation
Python
1
star
77

cambi.org

website in memorial to Cambi Evers-Everette (Coe)
CSS
1
star
78

test-node-path

application used to test require.main.filename on various platforms
JavaScript
1
star
79

cambiandben.com

the website for Cambi and Ben's wedding.
CSS
1
star
80

mtgdeck

build your Magic: The Gathering deck from the command-line
JavaScript
1
star
81

parseargs-yargs-parser

Shim that allows @pkgjs/parseargs to be used as drop in replacement for yargs-parser.
TypeScript
1
star
82

code-to-signal

map exit codes on Linux to named signals.
JavaScript
1
star
83

terminal-quiz

given a choices.txt, in a known location, prompts user for answer and writes to answer.txt
JavaScript
1
star
84

node-27566-bug

demonstration of wonky coverage reporting.
JavaScript
1
star
85

npm-tonic-app

tonic npm package addon
JavaScript
1
star
86

guesstimator

Estimates the performance of a distributed system based on a sample set of data.
Python
1
star
87

minimal-source-map

minimal implementation of SourceMap Revision 3
JavaScript
1
star
88

external-link-repo

Repo for debugging issues with linkinator when there are many external links in action
TypeScript
1
star
89

codecovorg

wrapper for codecov.io that fetches repo tokens based on API key
JavaScript
1
star
90

example-todo-cloud-run

redwood example TODO app running on Cloud Run
JavaScript
1
star
91

hack-illinois-chat

chat app built during Hack Illinois 2019
JavaScript
1
star