···1+# Pict-rs {#module-services-pict-rs}
2+3+pict-rs is a a simple image hosting service.
4+5+## Quickstart {#module-services-pict-rs-quickstart}
6+7+the minimum to start pict-rs is
8+9+```nix
10+services.pict-rs.enable = true;
11+```
12+13+this will start the http server on port 8080 by default.
14+15+## Usage {#module-services-pict-rs-usage}
16+17+pict-rs offers the following endpoints:
18+- `POST /image` for uploading an image. Uploaded content must be valid multipart/form-data with an
19+ image array located within the `images[]` key
20+21+ This endpoint returns the following JSON structure on success with a 201 Created status
22+ ```json
23+ {
24+ "files": [
25+ {
26+ "delete_token": "JFvFhqJA98",
27+ "file": "lkWZDRvugm.jpg"
28+ },
29+ {
30+ "delete_token": "kAYy9nk2WK",
31+ "file": "8qFS0QooAn.jpg"
32+ },
33+ {
34+ "delete_token": "OxRpM3sf0Y",
35+ "file": "1hJaYfGE01.jpg"
36+ }
37+ ],
38+ "msg": "ok"
39+ }
40+ ```
41+- `GET /image/download?url=...` Download an image from a remote server, returning the same JSON
42+ payload as the `POST` endpoint
43+- `GET /image/original/{file}` for getting a full-resolution image. `file` here is the `file` key from the
44+ `/image` endpoint's JSON
45+- `GET /image/details/original/{file}` for getting the details of a full-resolution image.
46+ The returned JSON is structured like so:
47+ ```json
48+ {
49+ "width": 800,
50+ "height": 537,
51+ "content_type": "image/webp",
52+ "created_at": [
53+ 2020,
54+ 345,
55+ 67376,
56+ 394363487
57+ ]
58+ }
59+ ```
60+- `GET /image/process.{ext}?src={file}&...` get a file with transformations applied.
61+ existing transformations include
62+ - `identity=true`: apply no changes
63+ - `blur={float}`: apply a gaussian blur to the file
64+ - `thumbnail={int}`: produce a thumbnail of the image fitting inside an `{int}` by `{int}`
65+ square using raw pixel sampling
66+ - `resize={int}`: produce a thumbnail of the image fitting inside an `{int}` by `{int}` square
67+ using a Lanczos2 filter. This is slower than sampling but looks a bit better in some cases
68+ - `crop={int-w}x{int-h}`: produce a cropped version of the image with an `{int-w}` by `{int-h}`
69+ aspect ratio. The resulting crop will be centered on the image. Either the width or height
70+ of the image will remain full-size, depending on the image's aspect ratio and the requested
71+ aspect ratio. For example, a 1600x900 image cropped with a 1x1 aspect ratio will become 900x900. A
72+ 1600x1100 image cropped with a 16x9 aspect ratio will become 1600x900.
73+74+ Supported `ext` file extensions include `png`, `jpg`, and `webp`
75+76+ An example of usage could be
77+ ```
78+ GET /image/process.jpg?src=asdf.png&thumbnail=256&blur=3.0
79+ ```
80+ which would create a 256x256px JPEG thumbnail and blur it
81+- `GET /image/details/process.{ext}?src={file}&...` for getting the details of a processed image.
82+ The returned JSON is the same format as listed for the full-resolution details endpoint.
83+- `DELETE /image/delete/{delete_token}/{file}` or `GET /image/delete/{delete_token}/{file}` to
84+ delete a file, where `delete_token` and `file` are from the `/image` endpoint's JSON
85+86+## Missing {#module-services-pict-rs-missing}
87+88+- Configuring the secure-api-key is not included yet. The envisioned basic use case is consumption on localhost by other services without exposing the service to the internet.
···1+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-pict-rs">
2+ <title>Pict-rs</title>
3+ <para>
4+ pict-rs is a a simple image hosting service.
5+ </para>
6+ <section xml:id="module-services-pict-rs-quickstart">
7+ <title>Quickstart</title>
8+ <para>
9+ the minimum to start pict-rs is
10+ </para>
11+ <programlisting language="bash">
12+services.pict-rs.enable = true;
13+</programlisting>
14+ <para>
15+ this will start the http server on port 8080 by default.
16+ </para>
17+ </section>
18+ <section xml:id="module-services-pict-rs-usage">
19+ <title>Usage</title>
20+ <para>
21+ pict-rs offers the following endpoints: -
22+ <literal>POST /image</literal> for uploading an image. Uploaded
23+ content must be valid multipart/form-data with an image array
24+ located within the <literal>images[]</literal> key
25+ </para>
26+ <programlisting>
27+This endpoint returns the following JSON structure on success with a 201 Created status
28+```json
29+{
30+ "files": [
31+ {
32+ "delete_token": "JFvFhqJA98",
33+ "file": "lkWZDRvugm.jpg"
34+ },
35+ {
36+ "delete_token": "kAYy9nk2WK",
37+ "file": "8qFS0QooAn.jpg"
38+ },
39+ {
40+ "delete_token": "OxRpM3sf0Y",
41+ "file": "1hJaYfGE01.jpg"
42+ }
43+ ],
44+ "msg": "ok"
45+}
46+```
47+</programlisting>
48+ <itemizedlist>
49+ <listitem>
50+ <para>
51+ <literal>GET /image/download?url=...</literal> Download an
52+ image from a remote server, returning the same JSON payload as
53+ the <literal>POST</literal> endpoint
54+ </para>
55+ </listitem>
56+ <listitem>
57+ <para>
58+ <literal>GET /image/original/{file}</literal> for getting a
59+ full-resolution image. <literal>file</literal> here is the
60+ <literal>file</literal> key from the <literal>/image</literal>
61+ endpoint’s JSON
62+ </para>
63+ </listitem>
64+ <listitem>
65+ <para>
66+ <literal>GET /image/details/original/{file}</literal> for
67+ getting the details of a full-resolution image. The returned
68+ JSON is structured like so:
69+ <literal>json { "width": 800, "height": 537, "content_type": "image/webp", "created_at": [ 2020, 345, 67376, 394363487 ] }</literal>
70+ </para>
71+ </listitem>
72+ <listitem>
73+ <para>
74+ <literal>GET /image/process.{ext}?src={file}&...</literal>
75+ get a file with transformations applied. existing
76+ transformations include
77+ </para>
78+ <itemizedlist spacing="compact">
79+ <listitem>
80+ <para>
81+ <literal>identity=true</literal>: apply no changes
82+ </para>
83+ </listitem>
84+ <listitem>
85+ <para>
86+ <literal>blur={float}</literal>: apply a gaussian blur to
87+ the file
88+ </para>
89+ </listitem>
90+ <listitem>
91+ <para>
92+ <literal>thumbnail={int}</literal>: produce a thumbnail of
93+ the image fitting inside an <literal>{int}</literal> by
94+ <literal>{int}</literal> square using raw pixel sampling
95+ </para>
96+ </listitem>
97+ <listitem>
98+ <para>
99+ <literal>resize={int}</literal>: produce a thumbnail of
100+ the image fitting inside an <literal>{int}</literal> by
101+ <literal>{int}</literal> square using a Lanczos2 filter.
102+ This is slower than sampling but looks a bit better in
103+ some cases
104+ </para>
105+ </listitem>
106+ <listitem>
107+ <para>
108+ <literal>crop={int-w}x{int-h}</literal>: produce a cropped
109+ version of the image with an <literal>{int-w}</literal> by
110+ <literal>{int-h}</literal> aspect ratio. The resulting
111+ crop will be centered on the image. Either the width or
112+ height of the image will remain full-size, depending on
113+ the image’s aspect ratio and the requested aspect ratio.
114+ For example, a 1600x900 image cropped with a 1x1 aspect
115+ ratio will become 900x900. A 1600x1100 image cropped with
116+ a 16x9 aspect ratio will become 1600x900.
117+ </para>
118+ </listitem>
119+ </itemizedlist>
120+ <para>
121+ Supported <literal>ext</literal> file extensions include
122+ <literal>png</literal>, <literal>jpg</literal>, and
123+ <literal>webp</literal>
124+ </para>
125+ <para>
126+ An example of usage could be
127+ <literal>GET /image/process.jpg?src=asdf.png&thumbnail=256&blur=3.0</literal>
128+ which would create a 256x256px JPEG thumbnail and blur it
129+ </para>
130+ </listitem>
131+ <listitem>
132+ <para>
133+ <literal>GET /image/details/process.{ext}?src={file}&...</literal>
134+ for getting the details of a processed image. The returned
135+ JSON is the same format as listed for the full-resolution
136+ details endpoint.
137+ </para>
138+ </listitem>
139+ <listitem>
140+ <para>
141+ <literal>DELETE /image/delete/{delete_token}/{file}</literal>
142+ or <literal>GET /image/delete/{delete_token}/{file}</literal>
143+ to delete a file, where <literal>delete_token</literal> and
144+ <literal>file</literal> are from the <literal>/image</literal>
145+ endpoint’s JSON
146+ </para>
147+ </listitem>
148+ </itemizedlist>
149+ </section>
150+ <section xml:id="module-services-pict-rs-missing">
151+ <title>Missing</title>
152+ <itemizedlist spacing="compact">
153+ <listitem>
154+ <para>
155+ Configuring the secure-api-key is not included yet. The
156+ envisioned basic use case is consumption on localhost by other
157+ services without exposing the service to the internet.
158+ </para>
159+ </listitem>
160+ </itemizedlist>
161+ </section>
162+</chapter>