README.md

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.