Permalink
Browse files

First commit, added all existing plugins

  • Loading branch information...
0 parents commit 834bb8d6538391f7e65b4194e25022c128cce43a @meltingice committed Dec 23, 2012
Showing with 1,174 additions and 0 deletions.
  1. +12 −0 README.md
  2. +76 −0 src/blur.coffee
  3. +146 −0 src/camera.coffee
  4. +348 −0 src/compoundBlur.coffee
  5. +20 −0 src/edges.coffee
  6. +9 −0 src/posterize.coffee
  7. +256 −0 src/presets.coffee
  8. +55 −0 src/size.coffee
  9. +238 −0 src/stackBlur.coffee
  10. +14 −0 src/threshold.coffee
@@ -0,0 +1,12 @@
+# CamanJS Plugins
+
+[CamanJS](https://github.com/meltingice/CamanJS) is an image manipulation library written in Javascript. This repository contains all plugins and features that are not a part of the core library.
+
+## Contributing
+
+Anyone is encouraged to contribute bug fixes or new features. The proper way to add a new feature is:
+
+1. Fork this repository.
+2. Create a new branch for the feature/plugin you're adding.
+3. Commit your changes.
+4. Send a pull request!
@@ -0,0 +1,76 @@
+Caman.Filter.register "boxBlur", ->
+ @processKernel "Box Blur", [
+ 1, 1, 1,
+ 1, 1, 1,
+ 1, 1, 1
+ ]
+
+Caman.Filter.register "radialBlur", ->
+ @processKernel "Radial Blur", [
+ 0, 1, 0,
+ 1, 1, 1,
+ 0, 1, 0
+ ]
+
+Caman.Filter.register "heavyRadialBlur", ->
+ @processKernel "Heavy Radial Blur", [
+ 0, 0, 1, 0, 0,
+ 0, 1, 1, 1, 0,
+ 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 0,
+ 0, 0, 1, 0, 0
+ ]
+
+Caman.Filter.register "gaussianBlur", ->
+ @processKernel "Gaussian Blur", [
+ 1, 4, 6, 4, 1,
+ 4, 16, 24, 16, 4,
+ 6, 24, 36, 24, 6,
+ 4, 16, 24, 16, 4,
+ 1, 4, 6, 4, 1
+ ]
+
+Caman.Filter.register "motionBlur", ->
+ if degrees in [0, 180]
+ kernel = [
+ 0, 0, 1, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 1, 0, 0
+ ]
+ else if (degrees > 0 && degrees < 90) || (degrees > 180 && degrees < 270)
+ kernel = [
+ 0, 0, 0, 0, 1,
+ 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0,
+ 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 0
+ ]
+ else if degrees in [90, 270]
+ kernel = [
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0
+ ]
+ else
+ kernel = [
+ 1, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 1
+ ]
+
+ @processKernel "Motion Blur", kernel
+
+Caman.Filter.register "sharpen", (amt = 100) ->
+ amt /= 100
+
+ @processKernel "Sharpen", [
+ 0, -amt, 0,
+ -amt, 4 * amt + 1, -amt,
+ 0, -amt, 0
+ ]
@@ -0,0 +1,146 @@
+vignetteFilters =
+ brightness: (rgba, amt, opts) ->
+ rgba.r = rgba.r - (rgba.r * amt * opts.strength)
+ rgba.g = rgba.g - (rgba.g * amt * opts.strength)
+ rgba.b = rgba.b - (rgba.b * amt * opts.strength)
+ rgba
+
+ gamma: (rgba, amt, opts) ->
+ rgba.r = Math.pow(rgba.r / 255, Math.max(10 * amt * opts.strength, 1)) * 255
+ rgba.g = Math.pow(rgba.g / 255, Math.max(10 * amt * opts.strength, 1)) * 255
+ rgba.b = Math.pow(rgba.b / 255, Math.max(10 * amt * opts.strength, 1)) * 255
+ rgba
+
+ colorize: (rgba, amt, opts) ->
+ rgba.r -= (rgba.r - opts.color.r) * amt;
+ rgba.g -= (rgba.g - opts.color.g) * amt;
+ rgba.b -= (rgba.b - opts.color.b) * amt;
+ rgba
+
+Filter.register "vignette", (size, strength = 60) ->
+ if typeof size is "string" and size.substr(-1) is "%"
+ if @dimensions.height > @dimensions.width
+ size = @dimensions.width * (parseInt(size.substr(0, size.length - 1), 10) / 100)
+ else
+ size = @dimensions.height * (parseInt(size.substr(0, size.length - 1), 10) / 100)
+
+ strength /= 100
+ center = [@dimensions.width / 2, @dimensions.height / 2]
+ start = Math.sqrt Math.pow(center[0], 2) + Math.pow(center[1], 2)
+ end = start - size
+ bezier = Calculate.bezier [0, 1], [30, 30], [70, 60], [100, 80]
+
+ @process "vignette", (rgba) ->
+ loc = @locationXY()
+ dist = Calculate.distance loc.x, loc.y, center[0], center[1]
+
+ if dist > end
+ div = Math.max 1, ((bezier[Math.round(((dist - end) / size) * 100)]/10) * strength)
+
+ rgba.r = Math.pow(rgba.r / 255, div) * 255
+ rgba.g = Math.pow(rgba.g / 255, div) * 255
+ rgba.b = Math.pow(rgba.b / 255, div) * 255
+
+ rgba
+
+Filter.register "rectangularVignette", (opts) ->
+ defaults =
+ strength: 50
+ cornerRadius: 0
+ method: 'brightness'
+ color:
+ r: 0
+ g: 0
+ b: 0
+
+ opts = Util.extend defaults, opts
+
+ if not opts.size
+ return @
+ else if typeof opts.size is "string"
+ percent = parseInt(opts.size, 10) / 100
+ opts.size =
+ width: @dimensions.width * percent
+ height: @dimensions.height * percent
+ else if typeof opts.size is "object"
+ for dim in ["width", "height"]
+ if typeof opts.size[dim] is "string"
+ opts.size[dim] = @dimensions[dim] * (parseInt(opts.size[dim], 10) / 100)
+ else if opts.size is "number"
+ size = opts.size
+ opts.size =
+ width: size
+ height: size
+
+ if typeof opts.cornerRadius is "string"
+ opts.cornerRadius = (opts.size.width / 2) * (parseInt(opts.cornerRadius, 10) / 100)
+
+ opts.strength /= 100
+
+ # Since pixels are discreet, force size to be an int
+ opts.size.width = Math.floor opts.size.width
+ opts.size.height = Math.floor opts.size.height
+ opts.image =
+ width: @dimensions.width
+ height: @dimensions.height
+
+ if opts.method is "colorize" and typeof opts.color is "string"
+ opts.color = Convert.hexToRGB opts.color
+
+ opts.coords =
+ left: (@dimensions.width - opts.size.width) / 2
+ right: @dimensions.width - opts.coords.left
+ bottom: (@dimensions.height - opts.size.height) / 2
+ top: @dimensions.height - opts.coords.bottom
+
+ opts.corners = [
+ {x: opts.coords.left + opts.cornerRadius, y: opts.coords.top - opts.cornerRadius},
+ {x: opts.coords.right - opts.cornerRadius, y: opts.coords.top - opts.cornerRadius},
+ {x: opts.coords.right - opts.cornerRadius, y: opts.coords.bottom + opts.cornerRadius},
+ {x: opts.coords.left + opts.cornerRadius, y: opts.coords.bottom + opts.cornerRadius}
+ ]
+
+ opts.maxDist = Calculate.distance(0, 0, opts.corners[3].x, opts.corners[3].y) - opts.cornerRadius
+
+ @process "rectangularVignette", (rgba) ->
+ loc = @locationXY()
+
+ # Trivial rejects
+ if (loc.x > opts.corners[0].x and loc.x < opts.corners[1].x) and (loc.y > opts.coords.bottom and loc.y < opts.coords.top)
+ return rgba
+ if (loc.x > opts.coords.left && loc.x < opts.coords.right) && (loc.y > opts.corners[3].y && loc.y < opts.corners[2].y)
+ return rgba
+
+ # Need to figure out which section we're in. First, the easy ones, then the harder ones.
+ if loc.x > opts.corners[0].x && loc.x < opts.corners[1].x && loc.y > opts.coords.top
+ # top-middle section
+ amt = (loc.y - opts.coords.top) / opts.maxDist
+ else if loc.y > opts.corners[2].y && loc.y < opts.corners[1].y && loc.x > opts.coords.right
+ # right-middle section
+ amt = (loc.x - opts.coords.right) / opts.maxDist
+ else if loc.x > opts.corners[0].x && loc.x < opts.corners[1].x && loc.y < opts.coords.bottom
+ # bottom-middle section
+ amt = (opts.coords.bottom - loc.y) / opts.maxDist
+ else if loc.y > opts.corners[2].y && loc.y < opts.corners[1].y && loc.x < opts.coords.left
+ # left-middle section
+ amt = (opts.coords.left - loc.x) / opts.maxDist
+ else if loc.x <= opts.corners[0].x && loc.y >= opts.corners[0].y
+ # top-left corner
+ radialDist = Caman.distance(loc.x, loc.y, opts.corners[0].x, opts.corners[0].y)
+ amt = (radialDist - opts.cornerRadius) / opts.maxDist
+ else if loc.x >= opts.corners[1].x && loc.y >= opts.corners[1].y
+ # top-right corner
+ radialDist = Caman.distance(loc.x, loc.y, opts.corners[1].x, opts.corners[1].y)
+ amt = (radialDist - opts.cornerRadius) / opts.maxDist
+ else if loc.x >= opts.corners[2].x && loc.y <= opts.corners[2].y
+ # bottom-right corner
+ radialDist = Caman.distance(loc.x, loc.y, opts.corners[2].x, opts.corners[2].y)
+ amt = (radialDist - opts.cornerRadius) / opts.maxDist
+ else if loc.x <= opts.corners[3].x && loc.y <= opts.corners[3].y
+ # bottom-left corner
+ radialDist = Caman.distance(loc.x, loc.y, opts.corners[3].x, opts.corners[3].y)
+ amt = (radialDist - opts.cornerRadius) / opts.maxDist
+
+ return rgba if amt < 0
+ return vignetteFilters[opts.method](rgba, amt, opts)
+
Oops, something went wrong.

0 comments on commit 834bb8d

Please sign in to comment.