{"id":14482518,"url":"https://github.com/sdepold/node-imageable","last_synced_at":"2025-10-15T21:10:24.661Z","repository":{"id":66448839,"uuid":"1799100","full_name":"sdepold/node-imageable","owner":"sdepold","description":"On-demand image manipulation middleware for express and connect.","archived":false,"fork":false,"pushed_at":"2014-12-11T11:23:18.000Z","size":502,"stargazers_count":167,"open_issues_count":12,"forks_count":13,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-02T08:22:29.231Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sdepold.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-05-25T13:56:37.000Z","updated_at":"2025-02-11T05:20:37.000Z","dependencies_parsed_at":"2023-02-20T12:45:56.008Z","dependency_job_id":null,"html_url":"https://github.com/sdepold/node-imageable","commit_stats":null,"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdepold%2Fnode-imageable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdepold%2Fnode-imageable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdepold%2Fnode-imageable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdepold%2Fnode-imageable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sdepold","download_url":"https://codeload.github.com/sdepold/node-imageable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250372465,"owners_count":21419719,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-03T00:01:10.526Z","updated_at":"2025-10-15T21:10:19.624Z","avatar_url":"https://github.com/sdepold.png","language":"JavaScript","readme":"# What is imageable doing?\n\nYou can put imageable into your express application, where it acts as middleware.\nCalling specific URLs (look below) will return resized and cropped images.\n\n# What will I need?\n\nBesides [Node.JS](http://nodejs.org) you will need [imagemagick](http://www.imagemagick.org) and eventually some other libs for image format handling. On a mac this is a fairly easy mission:\n\n```\nbrew install imagemagick\n```\n\n# How to get it run.\n\nIn your express app you will find a section like this:\n\n```js\napp.configure(function(){\n  app.use(express.bodyParser())\n  app.use(express.methodOverride())\n  //...\n  app.use(app.router)\n})\n```\n\nTo plug imageable into your app, just add the following ABOVE the router:\n\n```js\napp.use(imageable(config, options))\n```\n\nHere is what an app should look like:\n\n## app.js ##\n```js\nvar fs     = require(\"fs\")\n  , config = JSON.parse(fs.readFileSync(__dirname + \"/config/config.json\"))\n\napp.configure(function(){\n  app.use(express.bodyParser())\n  app.use(express.methodOverride())\n  app.use(imageable(config, {\n    before: function(stats) { console.log('before') },\n    after: function(stats, returnValueOfBefore, err) { console.log('after') }\n  }))\n  app.use(app.router)\n})\n```\n\nNotice that the after-callback will have the returned value of the before-callback as\nsecond parameter. Using that mechanism, you can for example track custom statistics.\nThe third parameter is furthermore containing an error if something went wrong. Nevertheless\nthe error gets thrown to end the request.\n\nThe middleware will automatically track some statistics, such as request,\naverage processing time etc. You can access them via the stats parameter.\n\n\n## config/config.json ##\n```js\n{\n  \"secret\":       \"my-very-secret-secret\",\n  \"magicHash\":    \"magic\",\n  \"namespace\":    \"\",\n  \"maxListeners\": 512,\n  \"imageSizeLimit\": 1024,\n  \"timeouts\": {\n    convert: 5000,\n    identify: 100,\n    download: 1000\n  }\n  \"reporting\": {\n    \"interval\": 10,\n    \"commands\": [\n      'curl -s http://foo.bar.org/report?avg=%{avg}',\n      'curl -s http://foo.bar.org/report?count=%{count}'\n    ]\n  },\n  \"whitelist\": {\n    \"allowedHosts\": [\".*google\\.com\", \".*facebook\\.com\"],\n    \"trustedHosts\": [\".*google\\.com\"]\n  },\n\n  // -- keepDownloads --\n  // Don't delete downloaded files but use them when the same url is requested twice.\n  // This can be pretty handy if you don't have a CDN in front of the resizer.\n  // Make sure that you always have enough HDD space !\n  //\n  // default: false\n  // added in: v0.10.0\n  \"keepDownloads\": true,\n\n  // -- maxDownloadCacheSize --\n  // If you keep downloads you would most probably want to limit the size\n  // of the download folder. Otherwise you will screw up your hard drive.\n  // Once the specified limit is reached node-imageable will start to delete\n  // the oldest files (20% of the existing files) in the download folder.\n  // The value is the number of megabytes you want to allow.\n  //\n  // tl;dr;\n  // Depending on the size of the source images, it might be not a good idea\n  // to set this value to less than 100. That's based on the fact that the\n  // server will only have a few files in the tmp folder and that deleting\n  // 20% of them will still result in a greater amount of used hdd space.\n  //\n  // default: null\n  // added in: v0.10.0\n  \"maxDownloadCacheSize\": 1000,\n\n  // -- tmpPathRoot --\n  // The folder you want to store the downloaded files in.\n  //\n  // default: /tmp/node-image-imagick\n  // added in: v0.10.0\n  \"tmpPathRoot\": process.cwd() + '/tmp'\n}\n```\n\nThe reporting config defines an array of commands which will get executed each _interval_ seconds.\u003cbr/\u003e\nThe whitelist config allows you furthermore to limit the hosts of image sources (allowedHosts) or\nto trust specific hosts (trustedHosts), so you don't have to specify the hash of the params (see below).\u003cbr/\u003e\nThe imageSizeLimit config can be used to specify a dimension limit. Setting it to 1024 will throw an error for requests like 1500x900.\u003cbr/\u003e\nThe timeouts config can be used to cancel slow downloads, long running converts or identify commands. Values are in milliseconds.\u003cbr/\u003e\nYou can also take a look at https://github.com/sdepold/node-imageable-server to get a further clue.\n\n# Routes and namespacing\n\nHere you can see the routes, imageable reacts on.\n\n    # resize an image with keeping ratio\n    http://localhost:3000/resize?url=http%3A%2F%2Fwww.google.com%2Fintl%2Fen_ALL%2Fimages%2Flogo.gif\u0026size=200x200\n\n    # resize an image to given size without keeping the ratio\n    http://localhost:3000/fit?url=http%3A%2F%2Fwww.google.com%2Fintl%2Fen_ALL%2Fimages%2Flogo.gif\u0026size=200x200\n\n    # crop a specific area of an image\n    http://localhost:3000/crop?url=http%3A%2F%2Fwww.google.com%2Fintl%2Fen_ALL%2Fimages%2Flogo.gif\u0026crop=200x200%2B20%2B40\n\n    # crop a specific area and resize it with keeping the ratio\n    http://localhost:3000/crop?url=http%3A%2F%2Fwww.google.com%2Fintl%2Fen_ALL%2Fimages%2Flogo.gif\u0026crop=200x200%2B20%2B40\u0026size=100x50\n\n    # if secret is provided in config/config.json, all urls must have a hash following the resize method (see Hashing)\n    http://localhost:3000/fit/-hash-?url=http%3A%2F%2Fwww.google.com%2Fintl%2Fen_ALL%2Fimages%2Flogo.gif\u0026size=200x200\n\n    # use the magic hash code that is valid for all requests, e.g. for testing\n    http://localhost:3000/fit/-magic-hash-?url=http%3A%2F%2Fwww.google.com%2Fintl%2Fen_ALL%2Fimages%2Flogo.gif\u0026size=200x200\n\n    # append any fancy name for nice looking urls and image downloads\n    http://localhost:3000/fit/-hash-/Fancy-Ignored-Name.gif?url=http%3A%2F%2Fwww.google.com%2Fintl%2Fen_ALL%2Fimages%2Flogo.gif\u0026size=200x200\n\n    # this is super edgy, but you can use it if you need it: scale the cropping clip according to another image dimension.\n    # this will calculate the ratio between the other image dimension and the passed (via url param) image's dimension and scale the cropping information (crop param)\n    http://localhost:3000/crop?url=http%3A%2F%2Fwww.google.com%2Fintl%2Fen_ALL%2Fimages%2Flogo.gif\u0026crop=200x200%2B20%2B40\u0026size=100x50\u0026cropSourceSize=500x\n\nIf you specify the namespace in your config (let's say to 'imageable'), all routes will be scoped to /imageable/fit... or /imageable/crop and so on.\n\n# Hashing\nTo make sure nobody missuses your image-server you can enable hashing in the config/config.json and all requests must be hashed.\n\n    # Node\n    var crypto    = require(\"crypto\")\n      , srcImgUrl = encodeURIComponent(\"http://www.google.com/intl/en_ALL/images/logo.gif\")\n      , query     = 'url=' + srcImgUrl + '\u0026size=200x200'\n      , hash      = crypto.createHash('md5').update(query + config.secret).digest(\"hex\").slice(0,8)\n      , url       = \"http://localhost:3000/resize/\" + hash + \"/Very-Nice-Image.gif?\" + query\n\n    res.send('\u003cimg src=\"' + url + '\" /\u003e')\n\n\n    # RUBY\n    require 'digest/md5'\n\n    def resized_image_tag(url, size)\n      query_options = {:url =\u003e url, :size =\u003e size}\n      digest        = Digest::MD5.new\n      hash          = digest.hexdigest(query_options.to_query + CFG[:node_imageable_secret])[0..7]\n\n      image_tag \"http://localhost:3000/resize/#{hash}/Very-Nice-Image.gif?#{query_options.to_query}\"\n    end\n\n    resized_image_tag(\"http://www.google.com/intl/en_ALL/images/logo.gif\", \"200x200\")\n\n# Running the tests\n\n    npm test\n\n# TODO\n\n - add 'expand' which would add whitespace to fill missing image areas\n\n# Authors/Contributors\n\n- DaWanda GmbH\n- Sascha Depold ([Twitter](http://twitter.com/sdepold) | [Github](http://github.com/sdepold) | [Website](http://depold.com))\n","funding_links":[],"categories":["📦 Legacy \u0026 Inactive Projects","JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsdepold%2Fnode-imageable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsdepold%2Fnode-imageable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsdepold%2Fnode-imageable/lists"}