ecaptcha
=====
Simple [Captcha](https://en.wikipedia.org/wiki/CAPTCHA) image generator for Erlang.
Zero dependencies! Pixels are generated by tiny C NIF. GIF and PNG encoders are pure-Erlang.
Flexible additional effects, multiple fonts, arbitrary colors, latin alphanumerics set of characters.
Covered by property-based tests. No segfaults, no memory-leaks.
Based on [Ivan Tikhonov's captcha library](https://github.com/ITikhonov/captcha).
Usage
-----
Add `ecaptcha` as a dependency to your project's rebar.config:
```erlang
{deps, [ecaptcha]}.
```
Then use one of the API functions to generate the image and short random text:
```erlang
{Phrase, PNGImage} = ecaptcha:png(
5,
#{effects => [line, blur, filter, dots, reverse_dots],
color => black,
alphabet => latin_uppercase,
font => <<"dejavusans">>}
).
```
`PNGImage` can be sent to the user with `Content-Type: image/png` and user have to guess
the 5-letter `Phrase` which is printed on the image.
`effects` option defines a set of different effects, which suppose to make it more difficult to
recognize the text with OCR systems:
* `line` - draws a curved horisontal line on top of the text
* `blur` - blurs the image (averages each pixel's color with it's neighbours)
* `filter` - makes letters hollow
* `dots` - draws 100 random 2x2 white dots on top of the image, effectively removing small patches
from it
* `reverse_dots` - draws 20 random dots of a randomized size from 1 to 3px using a color opposite
to the current color (so, reversing the color - black becomes white, white becomes black)
The more effects you apply, the more difficult it is to recognize the text on the image (for both
human and OCR).
`color` option defines the image's color. It doesn't affect Captcha strength, but can be used to match
your website / app style. You can select from a set of predefined colors: `black`, `red`, `orange`,
`blue`, `pink` or `purple`, or it can be provided as a 3-tuple `{Red, Green, Blue}`, `0..255`.
`alphabet` defines the set of characters that can be printed on the image. It can be one of the
predefined sets: `numbers` for 0-9, `latin_lowercase` for a-z, `latin_uppercase` for A-Z or it
can be a binary containing all the allowed characters (duplicates are ok), eg `<<"1234abcd">>`.
`font` binary name of one of the supported fonts. Function `fonts/0` can be used to get the list of
available fonts. Fonts are pre-rendered at NIF compile-time, see the `c_src/fonts.h` and
`FONTS` parameter in `c_src/Makefile`.
All the options are optional.
```erlang
ecaptcha:gif/2
```
Same as `ecaptcha:png/2`, but returns the image encoded in GIF format. `Content-Type: image/gif`.
```erlang
{Phrase, Pixels} = ecaptcha:pixels(5, #{font => <<"ubuntu-r">>, alphabet => numbers}).
```
`Phrase` is the same as above, but `Pixels` is a `200x70 = 14000` bytes binary of greyscale
pixels, from top-left to bottom-right, line-by-line. It can be used to, eg, display pixels with
JavaScript on a `<canvas>` etc. Options are the same as for `gif/2` or `png/2`, but `color` key
is obviously ignored.
```erlang
ecaptcha:fonts()
```
Returns a list of tuples containing information about each available font. Currently it's a 2-tuple
where 1st element is binary font name and 2nd element is binary containing all the characters of
the alphabet available for this font.
Image encoders
--------------
This library also contains pure-erlang PNG and GIF image format encoders.
See [ecaptcha_gif.erl](src/ecaptcha_gif.erl) and [ecaptcha_png.erl](src/ecaptcha_png.erl).
Their current API is not really a generic-purpose, but the implementation is quite flexible, so,
code can be adopted to encode arbitrary images, not only Captchas.