23 |
24 |
25 |
38 |
--------------------------------------------------------------------------------
/.vitepress/theme/index.ts:
--------------------------------------------------------------------------------
1 | import DefaultTheme, { VPImage } from 'vitepress/theme';
2 |
3 | import NewsList from './global-components/NewsList.vue';
4 |
5 | import './styles/custom.css';
6 | import './styles/layout.css';
7 | import 'line-awesome/dist/line-awesome/css/line-awesome.min.css';
8 |
9 | export default {
10 | extends: DefaultTheme,
11 | enhanceApp({ app }) {
12 | app.component('NewsList', NewsList);
13 | // https://github.com/vuejs/vitepress/issues/2813#issuecomment-1683915241
14 | app.component('Image', VPImage);
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/.vitepress/theme/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@weserv/docs-theme",
3 | "version": "0.2.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "@weserv/docs-theme",
9 | "version": "0.2.0",
10 | "license": "MIT",
11 | "devDependencies": {
12 | "line-awesome": "^1.3.0"
13 | }
14 | },
15 | "node_modules/line-awesome": {
16 | "version": "1.3.0",
17 | "resolved": "https://registry.npmjs.org/line-awesome/-/line-awesome-1.3.0.tgz",
18 | "integrity": "sha512-Y0YHksL37ixDsHz+ihCwOtF5jwJgCDxQ3q+zOVgaSW8VugHGTsZZXMacPYZB1/JULBi6BAuTCTek+4ZY/UIwcw==",
19 | "dev": true
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/.vitepress/theme/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@weserv/docs-theme",
3 | "version": "0.2.0",
4 | "description": "Default theme for wsrv.nl",
5 | "homepage": "https://github.com/weserv/docs#readme",
6 | "bugs": {
7 | "url": "https://github.com/weserv/images/issues"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/weserv/docs.git",
12 | "directory": ".vitepress/theme"
13 | },
14 | "license": "MIT",
15 | "author": "Kleis Auke Wolthuizen",
16 | "type": "module",
17 | "main": "index.ts",
18 | "devDependencies": {
19 | "line-awesome": "^1.3.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.vitepress/theme/styles/custom.css:
--------------------------------------------------------------------------------
1 | /** Base Styles */
2 | :root {
3 | /**
4 | * Colors
5 | * --------------------------------------------------------------------- */
6 |
7 | --vp-c-brand-1: #a72376; /* --vp-c-indigo-1 */
8 | --vp-c-brand-2: #c02888; /* --vp-c-indigo-2 */
9 | --vp-c-brand-3: #c63d93; /* --vp-c-indigo-3 */
10 | --vp-c-brand-soft: rgba(167, 35, 118, 0.14); /* --vp-c-indigo-soft */
11 |
12 | --vp-badge-info-text: var(--vp-c-white);
13 | --vp-badge-info-bg: var(--vp-c-brand);
14 | }
15 |
16 | .dark {
17 | --vp-badge-info-bg: var(--vp-c-brand-2);
18 | }
19 |
--------------------------------------------------------------------------------
/.vitepress/theme/styles/layout.css:
--------------------------------------------------------------------------------
1 | .logo {
2 | height: 2.2rem !important;
3 | }
4 |
5 | .icon {
6 | justify-content: left !important;
7 | background-color: var(--vp-c-bg-soft) !important;
8 | width: auto !important;
9 | height: auto !important;
10 | font-size: 112px !important;
11 | transition: none !important;
12 | }
13 |
14 | .cloudflare-logo {
15 | padding: 15px;
16 | }
17 |
18 | .features {
19 | display: flex;
20 | flex-wrap: wrap;
21 | margin: -20px -24px;
22 | }
23 |
24 | .feature {
25 | flex-shrink: 0;
26 | padding: 20px 15px;
27 | width: 100%;
28 | text-align: center;
29 | margin: 40px auto;
30 | }
31 |
32 | .feature a {
33 | display: block;
34 | color: var(--vp-c-text-1);
35 | text-decoration: none;
36 | }
37 |
38 | .feature i {
39 | position: relative;
40 | margin: 0 auto;
41 | font-size: 5rem;
42 | color: var(--vp-c-text-1);
43 | }
44 |
45 | .feature:hover,
46 | .feature:hover i,
47 | .feature:hover a {
48 | color: var(--vp-c-brand-1);
49 | }
50 |
51 | @media (min-width: 420px) {
52 | .feature {
53 | width: calc(100% / 2);
54 | }
55 | }
56 |
57 | @media (max-width: 420px) {
58 | .cloudflare-logo {
59 | width: 100%;
60 | }
61 | }
62 |
63 | @media (min-width: 768px) {
64 | .feature {
65 | width: calc(100% / 4);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019-present Andries Louw Wolthuizen and Kleis Auke Wolthuizen.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/adjustment.md:
--------------------------------------------------------------------------------
1 | # Adjustment
2 |
3 | Perform operations similar to those in image-editing applications.
4 |
5 | ## Background
6 |
7 | Sets the background color of the image. Supports a variety of color
8 | formats. In addition to the 140 color names supported by all modern browsers (listed [here](supported-colors.md)),
9 | it also accepts hexadecimal RGB and RBG alpha formats.
10 |
11 | **Valid hexadecimal formats:**
12 |
13 | - 3 digit RGB: `CCC`
14 | - 4 digit ARGB (alpha): `5CCC`
15 | - 6 digit RGB: `CCCCCC`
16 | - 8 digit ARGB (alpha): `55CCCCCC`
17 |
18 | More info: [Issue #81 - Background setting](https://github.com/weserv/images/issues/81).
19 |
20 | ::: code-group
21 |
22 | ```html [HTML]
23 |
24 | ```
25 |
26 | ```md [Markdown]
27 | 
28 | ```
29 |
30 | :::
31 |
32 | [](/?url=wsrv.nl/transparency_demo.png&w=400&bg=black){target="_blank"}
33 |
34 | ## Blur
35 |
36 | Adds a blur effect to the image. When used without a value (`&blur`), performs a fast, mild blur of the
37 | output image. When a value is provided, performs a slower, more accurate Gaussian blur.
38 |
39 | Use values between `0.3` and `1000`, representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
40 |
41 | More info: [Issue #69 - Allow blur transformation (with radius parameter)](https://github.com/weserv/images/issues/69).
42 |
43 | ::: code-group
44 |
45 | ```html [HTML]
46 |
47 | ```
48 |
49 | ```md [Markdown]
50 | 
51 | ```
52 |
53 | :::
54 |
55 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&blur=5){target="_blank"}
56 |
57 | ## Contrast
58 |
59 | Adjusts the image contrast. Use values between `-100` and `+100`, where `0` represents no change.
60 |
61 | ::: code-group
62 |
63 | ```html [HTML]
64 |
65 | ```
66 |
67 | ```md [Markdown]
68 | 
69 | ```
70 |
71 | :::
72 |
73 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&con=25){target="_blank"}
74 |
75 | ## Filter
76 |
77 | Applies a filter effect to the image. Accepts `greyscale`, `sepia`, `duotone` or `negate`.
78 |
79 | ::: tip
80 | You can use `&start` and `&stop` to define the duotone colors. By default, it will use
81 | &start=C83658 and
82 | &stop=D8E74F.
83 | :::
84 |
85 | ::: code-group
86 |
87 | ```html [HTML]
88 |
89 | ```
90 |
91 | ```md [Markdown]
92 | 
93 | ```
94 |
95 | :::
96 |
97 | [](/?url=wsrv.nl/zebra.jpg&w=300&h=300&fit=cover&a=focal&fpx=0.6&filt=duotone){target="_blank"}
98 |
99 | ## Gamma
100 |
101 | Adjusts the image gamma. Use values between `1.0` and `3.0`. The default value is `2.2`, a suitable
102 | approximation for sRGB images.
103 |
104 | ::: code-group
105 |
106 | ```html [HTML]
107 |
108 | ```
109 |
110 | ```md [Markdown]
111 | 
112 | ```
113 |
114 | :::
115 |
116 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&gam=3){target="_blank"}
117 |
118 | ## Modulate
119 |
120 | Transforms the image using brightness, saturation and hue rotation.
121 | Use `&mod=[brightness multiplier],[saturation multiplier],[hue degrees]` to define the below adjustments at once.
122 |
123 | ### Brightness
124 |
125 | Adjusts the brightness of the image. A multiplier greater than 1 will increase brightness, while a
126 | multiplier less than 1 will decrease the brightness.
127 |
128 | ::: code-group
129 |
130 | ```html [HTML]
131 |
132 | ```
133 |
134 | ```md [Markdown]
135 | 
136 | ```
137 |
138 | :::
139 |
140 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&mod=2){target="_blank"}
141 |
142 | ### Saturation
143 |
144 | Adjusts the saturation of the image. A multiplier greater than 1 will increase saturation, while a multiplier
145 | less than 1 will decrease the saturation.
146 |
147 | ::: code-group
148 |
149 | ```html [HTML]
150 |
151 | ```
152 |
153 | ```md [Markdown]
154 | 
155 | ```
156 |
157 | :::
158 |
159 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&sat=0.5){target="_blank"}
160 |
161 | ### Hue rotation
162 |
163 | Applies a hue rotation to the image. A positive hue rotation increases the hue value, while a negative
164 | rotation decreases the hue value.
165 |
166 | Values are given in degrees, there is no minimum or maximum value; `&hue=N` evaluates to `N` modulo 360.
167 |
168 | ::: code-group
169 |
170 | ```html [HTML]
171 |
172 | ```
173 |
174 | ```md [Markdown]
175 | 
176 | ```
177 |
178 | :::
179 |
180 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&hue=90){target="_blank"}
181 |
182 | ## Sharpen
183 |
184 | Sharpen the image. Performs an accurate sharpen of the L channel in the LAB color space. Use in combination with
185 | `&sharpf=` and `&sharpj=` to control the level of sharpening in "flat" and "jagged" areas.
186 |
187 | Use values between `0.000001` and `10`, representing the sigma of the Gaussian mask,
188 | where `sigma = 1 + radius / 2`. When used without parameters, performs a fast, mild
189 | sharpen of the output image.
190 |
191 | The level of sharpening to apply to "flat" (`&sharpf=`) and "jagged" (`&sharpj=`) areas needs
192 | to be given in the range of `0` and `1000000`.
193 |
194 | ::: code-group
195 |
196 | ```html [HTML]
197 |
198 | ```
199 |
200 | ```md [Markdown]
201 | 
202 | ```
203 |
204 | :::
205 |
206 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&sharp=3){target="_blank"}
207 |
208 | ## Tint
209 |
210 | Tint the image using the provided chroma while preserving the image luminance. See [here](adjustment.md#background)
211 | for the supported color formats.
212 |
213 | ::: code-group
214 |
215 | ```html [HTML]
216 |
217 | ```
218 |
219 | ```md [Markdown]
220 | 
221 | ```
222 |
223 | :::
224 |
225 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&tint=red){target="_blank"}
226 |
--------------------------------------------------------------------------------
/docs/crop.md:
--------------------------------------------------------------------------------
1 | # Crop
2 |
3 | Controls how the image is aligned.
4 |
5 | ## Alignment position
6 |
7 | How the image should be aligned when `&fit=cover` or `&fit=contain` is set. The [`&w=`](size.md#width) and [`&h=`](size.md#height)
8 | parameters should also be specified.
9 |
10 | ### Position-based
11 |
12 | Controls the starting location of the crop. When `&fit=contain` is set, it determines how the image is positioned inside its box.
13 |
14 | **Valid positions:**
15 |
16 | - `center`: default
17 | - `top`
18 | - `right`
19 | - `bottom`
20 | - `left`
21 | - `top-left`
22 | - `bottom-left`
23 | - `bottom-right`
24 | - `top-right`
25 |
26 | For more information, please see the suggestion on our GitHub issue tracker: [Issue #24 - Aligning](https://github.com/weserv/images/issues/24).
27 |
28 | ::: code-group
29 |
30 | ```html [HTML]
31 |
32 | ```
33 |
34 | ```md [Markdown]
35 | 
36 | ```
37 |
38 | :::
39 |
40 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&h=300&fit=cover&a=top){target="_blank"}
41 |
42 | ### Focal point
43 |
44 | You can be more specific about the alignment using a focal point. This can be set using a horizontal
45 | (`&fpx=`) and vertical (`&fpy=`) offset decimal value (a float between `0.0` and `1.0`, inclusive). The
46 | default value is `0.5`, or the center of the image.
47 |
48 | ::: code-group
49 |
50 | ```html [HTML]
51 |
52 | ```
53 |
54 | ```md [Markdown]
55 | 
56 | ```
57 |
58 | :::
59 |
60 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&h=300&fit=cover&a=focal&fpy=0.45){target="_blank"}
61 |
62 | ### Smart crop
63 |
64 | An experimental strategy-based approach to crop the image by removing boring parts. This only works
65 | with `&fit=cover`.
66 |
67 | More info: [Issue #90 - Add support for smart crop](https://github.com/weserv/images/issues/90).
68 |
69 | **Valid strategies:**
70 |
71 | - `entropy`: focus on the region with the highest [Shannon entropy](https://en.wikipedia.org/wiki/Entropy_%28information_theory%29).
72 | - `attention`: focus on the region with the highest luminance frequency, color saturation and
73 | presence of skin tones.
74 |
75 | ::: code-group
76 |
77 | ```html [HTML]
78 |
79 | ```
80 |
81 | ```md [Markdown]
82 | 
83 | ```
84 |
85 | :::
86 |
87 | [](/?url=wsrv.nl/puppy.jpg&w=300&h=300&fit=cover&a=attention){target="_blank"}
88 |
89 | ## Rectangle crop
90 |
91 | Crops the image to specific dimensions after any other resize operations.
92 |
93 | Use percentage values (denoted by a value ending with `%`) to crop a relative portion of the image.
94 |
95 | ::: tip
96 | You can use `&precrop`, for a pre-resize crop behaviour.
97 | See [Issue #176 - Combine cropping with resizing](https://github.com/weserv/images/issues/176) for more information.
98 | :::
99 |
100 | ::: code-group
101 |
102 | ```html [HTML]
103 |
104 | ```
105 |
106 | ```md [Markdown]
107 | 
108 | ```
109 |
110 | :::
111 |
112 | [](/?url=wsrv.nl/lichtenstein.jpg&cx=680&cy=500&cw=300&ch=300){target="_blank"}
113 |
114 | ## Trim
115 |
116 | Trim "boring" pixels from all edges that contain values within a similarity of the top-left pixel. Trimming
117 | occurs before any resize operation. Use values between `1` and `254` to define a tolerance level to trim
118 | away similar color values. You also can specify just `&trim`, which defaults to a tolerance level of `10`.
119 |
120 | More info: [Issue #39 - able to remove black/white whitespace](https://github.com/weserv/images/issues/39).
121 |
122 | ::: code-group
123 |
124 | ```html [HTML]
125 |
126 | ```
127 |
128 | ```md [Markdown]
129 | 
130 | ```
131 |
132 | :::
133 |
134 | [](/?url=wsrv.nl/transparency_demo.png&w=300&trim=10){target="_blank"}
135 |
--------------------------------------------------------------------------------
/docs/fit.md:
--------------------------------------------------------------------------------
1 | # Fit
2 |
3 | Controls how the image is fitted to its target dimensions. Below are a couple of examples. Some of these
4 | values are based on the [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) CSS property.
5 |
6 |
10 |
11 | ## Inside
12 |
13 | Default. Preserving aspect ratio, resize the image to be as large as possible while ensuring its dimensions
14 | are less than or equal to both those specified.
15 |
16 | ::: code-group
17 |
18 | ```html [HTML]
19 |
20 | ```
21 |
22 | ```md [Markdown]
23 | 
24 | ```
25 |
26 | :::
27 |
28 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&h=300&fit=inside){target="_blank"}
29 |
30 | ## Outside
31 |
32 | Preserving aspect ratio, resize the image to be as small as possible while ensuring its dimensions are
33 | greater than or equal to both those specified.
34 |
35 | ::: code-group
36 |
37 | ```html [HTML]
38 |
39 | ```
40 |
41 | ```md [Markdown]
42 | 
43 | ```
44 |
45 | :::
46 |
47 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&h=300&fit=outside){target="_blank"}
48 |
49 | ## Cover
50 |
51 | Crop the image to cover both provided dimensions.
52 |
53 | ::: code-group
54 |
55 | ```html [HTML]
56 |
57 | ```
58 |
59 | ```md [Markdown]
60 | 
61 | ```
62 |
63 | :::
64 |
65 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&h=300&fit=cover){target="_blank"}
66 |
67 | ## Fill
68 |
69 | Ignore the aspect ratio of the input and stretch to both provided dimensions.
70 |
71 | ::: code-group
72 |
73 | ```html [HTML]
74 |
75 | ```
76 |
77 | ```md [Markdown]
78 | 
79 | ```
80 |
81 | :::
82 |
83 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&h=300&fit=fill){target="_blank"}
84 |
85 | ## Contain
86 |
87 | Embed within both provided dimensions. The remaining space can be filled with a background color by
88 | using `&cbg=`. See [here](adjustment.md#background) for the supported color formats.
89 |
90 | More info: [Issue #80 - letterbox images that need to fit](https://github.com/weserv/images/issues/80).
91 |
92 | ::: code-group
93 |
94 | ```html [HTML]
95 |
96 | ```
97 |
98 | ```md [Markdown]
99 | 
100 | ```
101 |
102 | :::
103 |
104 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&h=300&fit=contain&cbg=black){target="_blank"}
105 |
106 | ## Without enlargement
107 |
108 | Do not enlarge if the width or height are already less than the specified dimensions.
109 |
110 | ::: code-group
111 |
112 | ```html [HTML]
113 |
114 | ```
115 |
116 | ```md [Markdown]
117 | 
118 | ```
119 |
120 | :::
121 |
--------------------------------------------------------------------------------
/docs/format.md:
--------------------------------------------------------------------------------
1 | # Format
2 |
3 | Controls the output properties of the image.
4 |
5 | ## Adaptive filter
6 |
7 | Use adaptive row filtering for reducing the PNG file size. This only works when the output image is `png`.
8 |
9 | ## Base64 (data URL)
10 |
11 | Encodes the image to be used directly in the src= of the ``-tag.
12 | Use [this link](/?url=wsrv.nl/lichtenstein.jpg&crop=100,100,720,530&encoding=base64){target="_blank"} to see the output result.
13 |
14 | More info: [Issue #59 - Return image base64 encoded](https://github.com/weserv/images/issues/59).
15 |
16 | ```
17 | //wsrv.nl/?url=wsrv.nl/lichtenstein.jpg&crop=100,100,720,530&encoding=base64
18 | ```
19 |
20 | ## Cache-Control
21 |
22 | Defines for how long an image should be cached by the browser. This will change the `max-age` of the
23 | `Cache-Control` HTTP-header.
24 |
25 | We define a "far-future expiration" of 1 year by default. The duration can be specified in days, weeks,
26 | months, and years using the following suffixes:
27 |
28 | - `d`: days
29 | - `w`: weeks, 7 days
30 | - `M`: months, 30 days
31 | - `y`: years, 365 days
32 |
33 | A duration must be in the range of `1d` (1 day) to `1y` (1 year), inclusive. Any other value will be ignored
34 | and fallback to the default value of 1 year.
35 |
36 | More info: [Issue #186 - Increase Cache-Control: max-age= to 1 year instead of 1 month](https://github.com/weserv/images/issues/186).
37 |
38 | ```
39 | //wsrv.nl?url=wsrv.nl/lichtenstein.jpg&w=100&maxage=31d
40 | ```
41 |
42 | ## Compression level
43 |
44 | The zlib compression level. Use a value between `0` (no Deflate) and `9` (maximum Deflate). The default
45 | value is `6`. This only works when the output image is `png`.
46 |
47 | ## Lossless compression
48 |
49 | Whether the resulting image should be lossless compressed. This only works when the output image is `webp`.
50 |
51 | More info: [Issue #386 - webP output is always lossy and cannot be requested as lossless](https://github.com/weserv/images/issues/386).
52 |
53 | ## Default image
54 |
55 | If there is a problem loading an image, then an error is shown. However, there might be a need where
56 | instead of giving a broken image to the user, you want a default image to be delivered.
57 |
58 | More info: [Issue #37 - Return default image if the image's URL not found](https://github.com/weserv/images/issues/37).
59 |
60 | The URL must not include a `default` querystring (if it does, it will be ignored).
61 |
62 | Use `&default=1` to redirect to the original URL specified in `?url=`.
63 |
64 | ::: code-group
65 |
66 | ```html [HTML]
67 |
68 | ```
69 |
70 | ```md [Markdown]
71 | 
72 | ```
73 |
74 | :::
75 |
76 | [](/?url=example.org/noimage.jpg&default=wsrv.nl/placeholder.svg){target="_blank"}
77 |
78 | ## Filename
79 |
80 | To specify the filename returned in the `Content-Disposition` header. The filename must only contain
81 | alphanumeric characters.
82 |
83 | More info: [Issue #122 - Specify filename](https://github.com/weserv/images/issues/122).
84 |
85 | ## Interlace / progressive
86 |
87 | Adds interlacing to GIF and PNG. JPEGs become progressive.
88 |
89 | More info: [Issue #50 - Add parameter to use progressive JPEGs](https://github.com/weserv/images/issues/50).
90 |
91 | ::: code-group
92 |
93 | ```html [HTML]
94 |
95 | ```
96 |
97 | ```md [Markdown]
98 | 
99 | ```
100 |
101 | :::
102 |
103 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&il){target="_blank"}
104 |
105 | ## Number of pages
106 |
107 | To select the number of pages to render. The default value is `1`. Set to `-1` to mean "until the end of
108 | the document".
109 |
110 | ::: tip
111 | `-1` will be useful if you need to resize an animated WebP or GIF image.
112 | :::
113 |
114 | ::: code-group
115 |
116 | ```html [HTML]
117 |
118 | ```
119 |
120 | ```md [Markdown]
121 | 
122 | ```
123 |
124 | :::
125 |
126 | [](/?url=wsrv.nl/banana.webp&h=300&output=gif&n=-1){target="_blank"}
127 |
128 | ## Output
129 |
130 | Encodes the image to a specific format. Accepts `jpg`, `png`, `gif`, `tiff`, `webp` or `json`. If none is
131 | given, it will honor the origin image format.
132 |
133 | More info: [Issue #62 - Format conversion](https://github.com/weserv/images/issues/62).
134 |
135 | ::: code-group
136 |
137 | ```html [HTML]
138 |
139 | ```
140 |
141 | ```md [Markdown]
142 | 
143 | ```
144 |
145 | :::
146 |
147 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&output=webp){target="_blank"}
148 |
149 | ## Page
150 |
151 | To load a given page (for an PDF, TIFF and multi-size ICO file). The value is numbered from zero. For a
152 | multi-resolution image, you can use `-1` to get the largest page and `-2` to get the smallest page.
153 |
154 | ## Quality
155 |
156 | Defines the quality of the image. Use values between `1` and `100`. Defaults to `80`. This only works
157 | when the output image is `jpg`, `tiff` or `webp`.
158 |
159 | ::: code-group
160 |
161 | ```html [HTML]
162 |
163 | ```
164 |
165 | ```md [Markdown]
166 | 
167 | ```
168 |
169 | :::
170 |
171 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&q=20){target="_blank"}
172 |
--------------------------------------------------------------------------------
/docs/introduction.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | **wsrv**.nl is an image **cache** & **resize** service. Our servers resize your image, cache it worldwide,
4 | and display it.
5 |
6 | - We support a good range of image formats, including JPEG, PNG, BMP, GIF, TIFF, WebP, PDF and SVG.
7 | - There's even support for [animated WebP and GIF images](format.md#number-of-pages).
8 | - We support IPv6, [serving dual stack](https://ipv6-test.com/validate.php?url=wsrv.nl), and supporting [IPv6-only origin hosts](/?url=ipv6.google.com/logos/logo.gif){target="_blank"}.
9 | - For secure connections over TLS/SSL, you can use [https://wsrv.nl/](/).
10 | - This can be very useful for embedding HTTP images on HTTPS websites. HTTPS origin hosts can be
11 | used by [prefixing the hostname with https://](https://github.com/weserv/images/issues/33).
12 | - The CDN is provided by [Cloudflare](https://www.cloudflare.com/). Images are being cached and delivered straight from
13 | [300+ global datacenters](https://www.cloudflare.com/network/). This ensures the fastest load times and best performance.
14 |
15 | ## How it works
16 |
17 | You pass the image URL and a set of parameters. wsrv.nl will then fetch the image, resize it,
18 | cache it and display it. The next time the request comes, it will serve the cached version.
19 |
20 | ::: tip
21 | If the URL includes a querystring, you'll need to ensure that it's properly URL-encoded, replacing
22 | `?` with `%3F` and `&` with `%26`, respectively.
23 | :::
24 |
25 | ::: code-group
26 |
27 | ```html [HTML]
28 |
29 |
30 | ```
31 |
32 | ```md [Markdown]
33 |
34 | 
35 | ```
36 |
37 | :::
38 |
--------------------------------------------------------------------------------
/docs/mask.md:
--------------------------------------------------------------------------------
1 | # Mask
2 |
3 | Controls the visible and non-visible area of the image.
4 |
5 | ## Mask type
6 |
7 | Sets the mask type from a predefined list of shapes.
8 |
9 | More info: [Issue #49 - Add circle effect to photos](https://github.com/weserv/images/issues/49).
10 |
11 | **Valid shapes:**
12 |
13 | - `circle`
14 | - `ellipse`
15 | - `triangle`
16 | - `triangle-180`: Triangle tilted upside down
17 | - `pentagon`
18 | - `pentagon-180`: Pentagon tilted upside down
19 | - `hexagon`
20 | - `square`: Square tilted 45 degrees
21 | - `star`: 5-point star
22 | - `heart`
23 |
24 | ::: code-group
25 |
26 | ```html [HTML]
27 |
28 | ```
29 |
30 | ```md [Markdown]
31 | 
32 | ```
33 |
34 | :::
35 |
36 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&h=300&fit=cover&mask=circle){target="_blank"}
37 |
38 | ## Mask trim
39 |
40 | Removes the remaining whitespace from the mask.
41 |
42 | ::: code-group
43 |
44 | ```html [HTML]
45 |
46 | ```
47 |
48 | ```md [Markdown]
49 | 
50 | ```
51 |
52 | :::
53 |
54 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300&h=900&fit=cover&a=crop-22-0&mask=circle&mtrim){target="_blank"}
55 |
56 | ## Mask background
57 |
58 | Sets the background color of the mask. See [here](adjustment.md#background) for the supported color formats.
59 |
60 | ::: code-group
61 |
62 | ```html [HTML]
63 |
64 | ```
65 |
66 | ```md [Markdown]
67 | 
68 | ```
69 |
70 | :::
71 |
72 | [](/?url=wsrv.nl/transparency_demo.png&w=400&bg=black&mask=heart&mbg=red){target="_blank"}
73 |
--------------------------------------------------------------------------------
/docs/orientation.md:
--------------------------------------------------------------------------------
1 | # Orientation
2 |
3 | Change the orientation of your image, by either flipping along its axes or rotating around the center.
4 |
5 | ## Flip
6 |
7 | Mirror the image vertically (up-down) about the x-axis.
8 | This always occurs after rotation, if any.
9 |
10 | ::: code-group
11 |
12 | ```html [HTML]
13 |
14 | ```
15 |
16 | ```md [Markdown]
17 | 
18 | ```
19 |
20 | :::
21 |
22 | [](/?url=wsrv.nl/lichtenstein.jpg&h=300&flip){target="_blank"}
23 |
24 | ## Flop
25 |
26 | Mirror the image horizontally (left-right) about the y-axis.
27 | This always occurs after rotation, if any.
28 |
29 | ::: code-group
30 |
31 | ```html [HTML]
32 |
33 | ```
34 |
35 | ```md [Markdown]
36 | 
37 | ```
38 |
39 | :::
40 |
41 | [](/?url=wsrv.nl/lichtenstein.jpg&h=300&flop){target="_blank"}
42 |
43 | ## Rotation
44 |
45 | Rotates the image by either an explicit angle or auto-orient based on the EXIF `Orientation` tag.
46 |
47 | If an angle is specified, it is converted to a valid positive degree rotation. For example, `-450` will
48 | produce a `270` degree rotation. When rotating by an angle other than a multiple of 90, the background
49 | color can be provided with the `&rbg=` parameter. See [here](adjustment.md#background) for the supported color formats.
50 |
51 | If no angle is provided, it is determined from the EXIF data.
52 |
53 | ::: code-group
54 |
55 | ```html [HTML]
56 |
57 | ```
58 |
59 | ```md [Markdown]
60 | 
61 | ```
62 |
63 | :::
64 |
65 | [](/?url=wsrv.nl/lichtenstein.jpg&h=300&ro=45&rbg=red){target="_blank"}
66 |
--------------------------------------------------------------------------------
/docs/quick-reference.md:
--------------------------------------------------------------------------------
1 | ---
2 | aside: false
3 | ---
4 |
5 | # Quick reference
6 |
7 | | Name | GET | Description | |
8 | | ----------------------- | ---------- | ----------------------------------------------------------------------- | ----------------------------: |
9 | | Width | `w` | Sets the width of the image, in pixels. | [info][width] |
10 | | Height | `h` | Sets the height of the image, in pixels. | [info][height] |
11 | | Device pixel ratio | `dpr` | Sets the output density of the image. | [info][dpr] |
12 | | Fit | `fit` | Sets how the image is fitted to its target dimensions. | [info][fit] |
13 | | Contain background | `cbg` | Sets the background color when using `&fit=contain`. | [info][contain-bg] |
14 | | Without enlargement | `we` | Do not enlarge the image. | [info][without-enlargement] |
15 | | Alignment position | `a` | Sets how the image is aligned. | [info][alignment-position] |
16 | | Rectangle crop | `crop` | Crops the image to specific dimensions. | [info][rectangle-crop] |
17 | | Pre-resize crop | `precrop` | A pre-resize crop behaviour. | [info][rectangle-crop] |
18 | | Trim | `trim` | Trim "boring" pixels from all edges. | [info][trim] |
19 | | Masking | `mask` | Sets the mask type from a predefined list. | [info][mask] |
20 | | Mask trim | `mtrim` | Removes the remaining whitespace from the mask. | [info][mask-trim] |
21 | | Mask background | `mbg` | Sets the background color of the mask. | [info][mask-bg] |
22 | | Flip | `flip` | Mirror the image vertically (up-down) about the x-axis. | [info][flip] |
23 | | Flop | `flop` | Mirror the image horizontally (left-right) about the y-axis. | [info][flop] |
24 | | Rotation | `ro` | Rotates the image. | [info][rotation] |
25 | | Rotation background | `rbg` | Sets the background color when rotating by arbitrary angles. | [info][rotation-bg] |
26 | | Background | `bg` | Sets the background color of the image. | [info][background] |
27 | | Blur | `blur` | Adds a blur effect to the image. | [info][blur] |
28 | | Contrast | `con` | Adjusts the image contrast. | [info][contrast] |
29 | | Filter | `filt` | Applies a filter effect to the image. | [info][filter] |
30 | | Gamma | `gam` | Adjusts the image gamma. | [info][gamma] |
31 | | Modulate | `mod` | Transforms the image using brightness, saturation and hue rotation. | [info][modulate] |
32 | | Saturation | `sat` | Adjusts the saturation of the image. | [info][saturation] |
33 | | Hue rotation | `hue` | Applies a hue rotation to the image. | [info][hue-rotation] |
34 | | Sharpen | `sharp` | Sharpen the image. | [info][sharpen] |
35 | | Tint | `tint` | Tint the image. | [info][tint] |
36 | | Adaptive filter | `af` | A filter algorithm that can be applied before compression. | [info][adaptive-filter] |
37 | | Base64 (data URL) | `encoding` | Encodes the image to be used directly in the `src=` of the ``-tag. | [info][base64] |
38 | | Cache-Control | `maxage` | How long an image should be cached by the browser. | [info][cache-control] |
39 | | Compression level | `l` | The zlib compression level. | [info][compression-level] |
40 | | Lossless compression | `ll` | Whether the resulting image should be lossless compressed. | [info][lossless-compression] |
41 | | Default image | `default` | Redirects to a default image when there is a problem loading an image. | [info][default] |
42 | | Filename | `filename` | To specify the filename. | [info][filename] |
43 | | Interlace / progressive | `il` | Adds interlacing to GIF and PNG. JPEG's become progressive. | [info][interlace-progressive] |
44 | | Number of pages | `n` | To select the the number of pages to render. | [info][n-pages] |
45 | | Output | `output` | Encodes the image to a specific format. | [info][output] |
46 | | Page | `page` | To load a given page. | [info][page] |
47 | | Quality | `q` | Defines the quality of the image. | [info][quality] |
48 |
49 | [width]: size.md#width
50 | [height]: size.md#height
51 | [dpr]: size.md#device-pixel-ratio
52 | [fit]: fit.md
53 | [contain-bg]: fit.md#contain
54 | [without-enlargement]: fit.md#without-enlargement
55 | [alignment-position]: crop.md#alignment-position
56 | [rectangle-crop]: crop.md#rectangle-crop
57 | [trim]: crop.md#trim
58 | [mask]: mask.md#mask-type
59 | [mask-trim]: mask.md#mask-trim
60 | [mask-bg]: mask.md#mask-background
61 | [flip]: orientation.md#flip
62 | [flop]: orientation.md#flop
63 | [rotation]: orientation.md#rotation
64 | [rotation-bg]: orientation.md#rotation
65 | [background]: adjustment.md#background
66 | [blur]: adjustment.md#blur
67 | [contrast]: adjustment.md#contrast
68 | [filter]: adjustment.md#filter
69 | [gamma]: adjustment.md#gamma
70 | [modulate]: adjustment.md#modulate
71 | [saturation]: adjustment.md#saturation
72 | [hue-rotation]: adjustment.md#hue-rotation
73 | [sharpen]: adjustment.md#sharpen
74 | [tint]: adjustment.md#tint
75 | [adaptive-filter]: format.md#adaptive-filter
76 | [base64]: format.md#base64-data-url
77 | [cache-control]: format.md#cache-control
78 | [compression-level]: format.md#compression-level
79 | [lossless-compression]: format.md#lossless-compression
80 | [default]: format.md#default-image
81 | [filename]: format.md#filename
82 | [interlace-progressive]: format.md#interlace-progressive
83 | [n-pages]: format.md#number-of-pages
84 | [output]: format.md#output
85 | [page]: format.md#page
86 | [quality]: format.md#quality
87 |
--------------------------------------------------------------------------------
/docs/size.md:
--------------------------------------------------------------------------------
1 | # Size
2 |
3 | Controls how the image needs to be resized. You can use both `&w=` and `&h=` parameters or only one
4 | of them: the other dimension is automatically updated.
5 |
6 | ## Width
7 |
8 | Sets the width of the image, in pixels.
9 |
10 | ::: code-group
11 |
12 | ```html [HTML]
13 |
14 | ```
15 |
16 | ```md [Markdown]
17 | 
18 | ```
19 |
20 | :::
21 |
22 | [](/?url=wsrv.nl/lichtenstein.jpg&w=300){target="_blank"}
23 |
24 | ## Height
25 |
26 | Sets the height of the image, in pixels.
27 |
28 | ::: code-group
29 |
30 | ```html [HTML]
31 |
32 | ```
33 |
34 | ```md [Markdown]
35 | 
36 | ```
37 |
38 | :::
39 |
40 | [](/?url=wsrv.nl/lichtenstein.jpg&h=300){target="_blank"}
41 |
42 | ## Device pixel ratio
43 |
44 | The device pixel ratio is used to easily convert between CSS pixels and device pixels. This makes it
45 | possible to display images at the correct pixel density on a variety of devices such as Apple devices with
46 | Retina Displays and Android devices. You must specify either a width, a height, or both for this parameter
47 | to work. Use values between `1` and `8`.
48 |
49 | More info: [Issue #115 - DPI support](https://github.com/weserv/images/issues/115).
50 |
51 | ::: code-group
52 |
53 | ```html [HTML]
54 |
55 | ```
56 |
57 | ```md [Markdown]
58 | 
59 | ```
60 |
61 | :::
62 |
63 | [](/?url=wsrv.nl/lichtenstein.jpg&h=144&dpr=2){target="_blank"}
64 |
--------------------------------------------------------------------------------
/docs/supported-colors.md:
--------------------------------------------------------------------------------
1 | ---
2 | aside: false
3 | ---
4 |
5 | # Supported colors
6 |
7 |
8 |
9 |
10 |
Name
11 |
Color
12 |
13 |
14 |
15 |
16 |
aliceblue
17 |
18 |
19 |
20 |
antiquewhite
21 |
22 |
23 |
24 |
aqua
25 |
26 |
27 |
28 |
aquamarine
29 |
30 |
31 |
32 |
azure
33 |
34 |
35 |
36 |
beige
37 |
38 |
39 |
40 |
bisque
41 |
42 |
43 |
44 |
black
45 |
46 |
47 |
48 |
blanchedalmond
49 |
50 |
51 |
52 |
blue
53 |
54 |
55 |
56 |
blueviolet
57 |
58 |
59 |
60 |
brown
61 |
62 |
63 |
64 |
burlywood
65 |
66 |
67 |
68 |
cadetblue
69 |
70 |
71 |
72 |
chartreuse
73 |
74 |
75 |
76 |
chocolate
77 |
78 |
79 |
80 |
coral
81 |
82 |
83 |
84 |
cornflowerblue
85 |
86 |
87 |
88 |
cornsilk
89 |
90 |
91 |
92 |
crimson
93 |
94 |
95 |
96 |
cyan
97 |
98 |
99 |
100 |
darkblue
101 |
102 |
103 |
104 |
darkcyan
105 |
106 |
107 |
108 |
darkgoldenrod
109 |
110 |
111 |
112 |
darkgray
113 |
114 |
115 |
116 |
darkgreen
117 |
118 |
119 |
120 |
darkkhaki
121 |
122 |
123 |
124 |
darkmagenta
125 |
126 |
127 |
128 |
darkolivegreen
129 |
130 |
131 |
132 |
darkorange
133 |
134 |
135 |
136 |
darkorchid
137 |
138 |
139 |
140 |
darkred
141 |
142 |
143 |
144 |
darksalmon
145 |
146 |
147 |
148 |
darkseagreen
149 |
150 |
151 |
152 |
darkslateblue
153 |
154 |
155 |
156 |
darkslategray
157 |
158 |
159 |
160 |
darkturquoise
161 |
162 |
163 |
164 |
darkviolet
165 |
166 |
167 |
168 |
deeppink
169 |
170 |
171 |
172 |
deepskyblue
173 |
174 |
175 |
176 |
dimgray
177 |
178 |
179 |
180 |
dodgerblue
181 |
182 |
183 |
184 |
firebrick
185 |
186 |
187 |
188 |
floralwhite
189 |
190 |
191 |
192 |
forestgreen
193 |
194 |
195 |
196 |
fuchsia
197 |
198 |
199 |
200 |
gainsboro
201 |
202 |
203 |
204 |
ghostwhite
205 |
206 |
207 |
208 |
gold
209 |
210 |
211 |
212 |
goldenrod
213 |
214 |
215 |
216 |
gray
217 |
218 |
219 |
220 |
green
221 |
222 |
223 |
224 |
greenyellow
225 |
226 |
227 |
228 |
honeydew
229 |
230 |
231 |
232 |
hotpink
233 |
234 |
235 |
236 |
indianred
237 |
238 |
239 |
240 |
indigo
241 |
242 |
243 |
244 |
ivory
245 |
246 |
247 |
248 |
khaki
249 |
250 |
251 |
252 |
lavender
253 |
254 |
255 |
256 |
lavenderblush
257 |
258 |
259 |
260 |
lawngreen
261 |
262 |
263 |
264 |
lemonchiffon
265 |
266 |
267 |
268 |
lightblue
269 |
270 |
271 |
272 |
lightcoral
273 |
274 |
275 |
276 |
lightcyan
277 |
278 |
279 |
280 |
lightgoldenrodyellow
281 |
282 |
283 |
284 |
lightgray
285 |
286 |
287 |
288 |
lightgreen
289 |
290 |
291 |
292 |
lightpink
293 |
294 |
295 |
296 |
lightsalmon
297 |
298 |
299 |
300 |
lightseagreen
301 |
302 |
303 |
304 |
lightskyblue
305 |
306 |
307 |
308 |
lightslategray
309 |
310 |
311 |
312 |
lightsteelblue
313 |
314 |
315 |
316 |
lightyellow
317 |
318 |
319 |
320 |
lime
321 |
322 |
323 |
324 |
limegreen
325 |
326 |
327 |
328 |
linen
329 |
330 |
331 |
332 |
magenta
333 |
334 |
335 |
336 |
maroon
337 |
338 |
339 |
340 |
mediumaquamarine
341 |
342 |
343 |
344 |
mediumblue
345 |
346 |
347 |
348 |
mediumorchid
349 |
350 |
351 |
352 |
mediumpurple
353 |
354 |
355 |
356 |
mediumseagreen
357 |
358 |
359 |
360 |
mediumslateblue
361 |
362 |
363 |
364 |
mediumspringgreen
365 |
366 |
367 |
368 |
mediumturquoise
369 |
370 |
371 |
372 |
mediumvioletred
373 |
374 |
375 |
376 |
midnightblue
377 |
378 |
379 |
380 |
mintcream
381 |
382 |
383 |
384 |
mistyrose
385 |
386 |
387 |
388 |
moccasin
389 |
390 |
391 |
392 |
navajowhite
393 |
394 |
395 |
396 |
navy
397 |
398 |
399 |
400 |
oldlace
401 |
402 |
403 |
404 |
olive
405 |
406 |
407 |
408 |
olivedrab
409 |
410 |
411 |
412 |
orange
413 |
414 |
415 |
416 |
orangered
417 |
418 |
419 |
420 |
orchid
421 |
422 |
423 |
424 |
palegoldenrod
425 |
426 |
427 |
428 |
palegreen
429 |
430 |
431 |
432 |
paleturquoise
433 |
434 |
435 |
436 |
palevioletred
437 |
438 |
439 |
440 |
papayawhip
441 |
442 |
443 |
444 |
peachpuff
445 |
446 |
447 |
448 |
peru
449 |
450 |
451 |
452 |
pink
453 |
454 |
455 |
456 |
plum
457 |
458 |
459 |
460 |
powderblue
461 |
462 |
463 |
464 |
purple
465 |
466 |
467 |
468 |
rebeccapurple
469 |
470 |
471 |
472 |
red
473 |
474 |
475 |
476 |
rosybrown
477 |
478 |
479 |
480 |
royalblue
481 |
482 |
483 |
484 |
saddlebrown
485 |
486 |
487 |
488 |
salmon
489 |
490 |
491 |
492 |
sandybrown
493 |
494 |
495 |
496 |
seagreen
497 |
498 |
499 |
500 |
seashell
501 |
502 |
503 |
504 |
sienna
505 |
506 |
507 |
508 |
silver
509 |
510 |
511 |
512 |
skyblue
513 |
514 |
515 |
516 |
slateblue
517 |
518 |
519 |
520 |
slategray
521 |
522 |
523 |
524 |
snow
525 |
526 |
527 |
528 |
springgreen
529 |
530 |
531 |
532 |
steelblue
533 |
534 |
535 |
536 |
tan
537 |
538 |
539 |
540 |
teal
541 |
542 |
543 |
544 |
thistle
545 |
546 |
547 |
548 |
tomato
549 |
550 |
551 |
552 |
turquoise
553 |
554 |
555 |
556 |
violet
557 |
558 |
559 |
560 |
wheat
561 |
562 |
563 |
564 |
white
565 |
566 |
567 |
568 |
whitesmoke
569 |
570 |
571 |
572 |
yellow
573 |
574 |
575 |
576 |
yellowgreen
577 |
578 |
579 |
580 |
581 |
--------------------------------------------------------------------------------
/faq/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar: false
3 | ---
4 |
5 | # FAQ
6 |
7 | ## What is wsrv.nl?
8 |
9 | wsrv.nl is an image service which is free for use to anyone, and we offer it as-is, it's just basic
10 | image resizing, available to anyone, easy to use. We try to keep everyone as happy as we can.
11 |
12 | ## What is this page? Where do I find my question?
13 |
14 | An FAQ is a list of frequently asked questions and answers. On this page we do our best to address
15 | concerns, and explain some inner workings of our service.
16 |
17 | You may scroll down to try to find your question. We also provide documentation you can read, and
18 | there is always our [GitHub][weserv-github] to assist you.
19 |
20 | ## What is the history of this project?
21 |
22 | The project started around 2007 on some spare servers. It was targeted at customers, to be used in
23 | websites, web applications and mobile applications. By making it freely available, it saved traffic (through
24 | compression) and offloaded the main servers, because customers didn't have to use poor self-written
25 | scripts for image resizing. We gained experience with different user cases, and the separation from the
26 | main servers enabled us to use the latest and greatest software stack.
27 |
28 | ## How are you funded?
29 |
30 | Since 2011 wsrv.nl is privately funded, and used as a testbed for new techniques in resizing,
31 | recognition and processing. Operating costs of the image service are very low. To prevent conflicts of
32 | interest, we never accepted any (financial) compensation or donation since we started, and we don't
33 | affiliate. Our intent is to keep the service running for many years to come.
34 |
35 | Try it for yourself, if you experience problems or if it doesn't meet expectations, contact us.
36 |
37 | ## Are there any limitations?
38 |
39 | There is a filter on the origin domain name. This means that we refuse to download images from certain
40 | websites, to prevent our service from being blocked by others. This filtering is handled by [OpenDNS
41 | domain tagging][opendns-domain-tagging].
42 |
43 | Furthermore, there is a request limit per visitor IP for uncached requests, which is 2500 images per 10
44 | minutes, after which the IP-address will be blocked for 1 hour.
45 |
46 | We are not a fan of filtering or limitations, but even more so, we are not a fan of being filtered. It is
47 | always possible to use our open source code, without filtering and limitations, on your own server.
48 |
49 | ## Is the code open source?
50 |
51 | Yes, it is! It is distributed under the open source [BSD 3-Clause license][weserv-license], check our [GitHub][weserv-github] for more
52 | information.
53 |
54 | ## How do I use your source code?
55 |
56 | The easiest way is to use Docker. After you have installed Docker, follow the [Docker installation
57 | instructions][weserv-docker] on using our source code with Docker.
58 |
59 | ## Can I sell your service?
60 |
61 | Sure, the [BSD 3-Clause license][weserv-license] permits you to use our code in your product, but please don't use our
62 | name in your marketing materials. Using the free service provided on wsrv.nl in your products
63 | is also permitted, but be reminded that our support is best-effort.
64 |
65 | If you really mean to sell our free service to other people as-is; I guess you're an amazing salesman, or
66 | we are terrible at it, but we do enjoy some good competition!
67 |
68 | ## Do you keep any logs?
69 |
70 | Yes, we do, for 7 days, after which they will be deleted automatically. The log is kept only on the server
71 | that processes your request. We don't share these logs, or store them in any other place. More
72 | information on how we collect, store and use any data, can be found in our [privacy policy][weserv-privacy-policy].
73 |
74 | ## Where are your servers located?
75 |
76 | Our servers are located near Paris (France) and Falkenstein (Germany). We also use Cloudflare, [Cloudflare
77 | has servers more close to your location][cloudflare-network], and they are fast.
78 |
79 | For now, our servers are with [OVH][ovh], [Scaleway][scaleway] and [Hetzner][hetzner] this may change in the future. We've
80 | always used servers located within the European Union, and continue to do so.
81 |
82 | ## What IP addresses does wsrv.nl use to fetch my images?
83 |
84 | A complete list of the IPs we use for outbound traffic can be found [here][ip-list].
85 |
86 | ## How is your relationship with Cloudflare?
87 |
88 | Wonderful, thanks for asking! Seriously, they provide awesome service, and are amazing to work with.
89 |
90 | ## What is your relationship with Cloudflare?
91 |
92 | We've started this service in 2007, use [Cloudflare](https://www.cloudflare.com/) since early 2012, and are on the free-tier since 2015.
93 | Costs for the servers to support wsrv.nl are really low, and it serves as a great testbed for new
94 | technologies. Cloudflare is based on the same [principles to provide their services][cloudflare-cdn].
95 |
96 | ## Is there any SLA or uptime guarantee for your service?
97 |
98 | Uptime guarantees buy you nothing but expensive insurance policies. We've had 99,993% uptime on
99 | average since 2007, all based on best-effort from all sides. Our service will not be the best fit for
100 | everyone: if you need more guarantees, anything besides best-effort, we encourage you to use our
101 | config and code as provided on our [GitHub][weserv-github], and build your own solution. We're always happy to help
102 | with questions that may arise if you do so.
103 |
104 | Besides, our service is free, so there is nothing to pay you back. If you want to help us, please do so by
105 | reporting any bugs, problems, and/or reviewing our code!
106 |
107 | ## What companies are using this service?
108 |
109 | Due to privacy concerns we're unable to share names, even if we were able to do so technically.
110 |
111 | Our service is mainly used by ISP's, dealerships, real estate agencies, shops, social networks and mobile
112 | app developers. Our reach is global, and we fetch images from 300.000 different unique domains.
113 |
114 | ## Are you passing any information to the origin server?
115 |
116 | We don't send any details to the server where the original image is kept. All requests for the original
117 | image are done anonymously from our servers. The only two things the request from our server has in
118 | common with your request is: 1. the address of the original image, and 2. the time you make the request.
119 |
120 | ## Will you see my images? Can others see my images?
121 |
122 | We are not interested in the images you ask us to process.
123 |
124 | The only exception is if there is a technical oddity in an image which causes strange behavior on our
125 | server(s). If you ask us to process such an image, we may try to copy the technical bits that causes the
126 | strange behavior. But we will never show others any (real) part of your image.
127 |
128 | Your images are private, and will not be shared, unless you tell us so. Other people can always use the
129 | same link (web address / URL) as you use, but we will not share any web addresses or logs.
130 |
131 | But please, always be careful of what you put on the internet, and who you trust online. If you don't trust
132 | our servers, or Cloudflare, you can use [our open source code][weserv-github] on your server(s).
133 |
134 | ## Are you saving images on your server(s)?
135 |
136 | We only save images to process them, only the processed images are kept for a short time (in cache).
137 |
138 | ## If images are modified, do you refresh them after a certain period of time?
139 |
140 | We do, but there is some caching.
141 |
142 | ## What is caching?
143 |
144 | A cache is a place where data (such as images) is temporary stored, to improve performance when the data
145 | is requested again. If the data is requested again, it may be served from the cache. For this service,
146 | the most important bits are our server cache, and your browser cache.
147 |
148 | ## How are images cached by your servers?
149 |
150 | We cache images in different ways, depending on the rate of requests, no more than 31 days, and most
151 | often at least 7 days.
152 |
153 | We utilize the [proxy cache in nginx][nginx-cache] to accomplish this, on top of that, [Cloudflare][cloudflare] caches the most
154 | frequently accessed images globally.
155 |
156 | Our servers only initiate a refresh when all caches have expired, and only when the image is still being
157 | requested by end users.
158 |
159 | The rules we use for server-side caching are different from the ones you see in the headers we provide
160 | for browsers.
161 |
162 | ## How are images cached by my browser?
163 |
164 | We ask the browser to cache images for 31536000 seconds, or 1 year. But it is up to the browser to do
165 | so.
166 |
167 | You can always clear your browser cache. Unfortunately, it is not possible for us (or our servers) to clear
168 | your browser cache.
169 |
170 | ## Can I remove an image from your server(s) cache?
171 |
172 | Not yet, a method to remove anything from our server side cache is still worked on. You can follow
173 | [Issue #14 - Remove cached images (by API/manual)][cache-removal-tool] for further updates.
174 |
175 | ## Why am I redirected to https:// even when I request http://?
176 |
177 | For added security we use [HSTS][hsts] to let modern browsers know that they can and should use HTTPS, we
178 | don't send any redirect headers ourselves, this is being done by your browser. It prevents any
179 | opportunistic MITM attacks.
180 |
181 | ## Are images compressed in any way?
182 |
183 | GZip compression is disabled, because it increases file sizes for JPEG-images, and it increases CPU-load
184 | on the client and server.
185 |
186 | JPEG-compression is honored, and is by default used when requesting BMP-images (they are converted
187 | to JPEG). If you want to modify compression for JPEG-images, you can do so by setting the [`&q=`][quality]
188 | parameter.
189 |
190 | ## Which file-extensions do you support?
191 |
192 | We "officially" support JPEG, PNG, GIF, TIFF, WebP, PDF and SVG as image input. "Unofficially" we're
193 | supporting all [libMagick image file types][magick-formats].
194 |
195 | ## Do you support animated images? E.g. animated .gif?
196 |
197 | We support animated WebP and GIF images through the use of [`&n=-1`][n-pages]. By default, the first frame of
198 | each image is processed. We don't support APNG, since the official libpng reference implementation
199 | doesn't support this extension.
200 |
201 | ## Can I use my own (sub)domain? E.g. by using a CNAME to wsrv.nl?
202 |
203 | We offer this service only on the wsrv.nl domain, and we offer it as-is. However, if you want to
204 | use it under your own (sub)domain, please see our [GitHub][weserv-github] to use it on your own server(s).
205 |
206 | ## Why don't you support CNAME-ing?
207 |
208 | The goal of this service is reaching out to starting websites that don't have the skills nor resources to
209 | script and host something themselves. But we don't want to serve the whole internet, aside from the
210 | amount of traffic (we already handle millions of requests per hour, which is great), our opinion is that
211 | when sites grow, they probably want to host their own solution. This solution will probably integrate
212 | better with their site(s), and will offer many advantages we just can't.
213 |
214 | ## Why am I not seeing any HTTP 304 header when I request a cached image?
215 |
216 | This is because we don't use Last-Modified headers.
217 |
218 | ## Why don't you use ETag or Last-Modified headers?
219 |
220 | We disable 2 (default) settings regarding cache-control. These are the ETag header, and the Last-
221 | Modified header.
222 |
223 | We do set the Cache-Control header, which can be controlled via the [`&max-age=`][cache-control] parameter. Allow me
224 | to explain this decision, using nginx and Apache configuration.
225 |
226 | Consider the following nginx and Apache settings, these are identical to the settings we use:
227 |
228 | ::: code-group
229 |
230 | ```nginx
231 | http {
232 | etag off; # Disable ETag header
233 | expires 1y; # Far-future expiration
234 | }
235 | ```
236 |
237 | ```apache [Apache]
238 | Header unset ETag
239 | FileETag None
240 | Header set Cache-Control "max-age=31536000"
241 | ```
242 |
243 | :::
244 |
245 | These directives completely disables ETags, so the browser is somewhat forced to listen to the Cache-
246 | Control header. It also tells the browser to cache the file 31536000 seconds, or 1 year.
247 |
248 | Optional, we use multiple servers to serve static content, and we are not sure about the last-modified
249 | times those servers report, because each has his own version of the cache, so we also use:
250 |
251 | ::: code-group
252 |
253 | ```nginx
254 | http {
255 | add_header Last-Modified "" always; # Always remove the Last-Modified header
256 | }
257 | ```
258 |
259 | ```apache [Apache]
260 | Header unset Last-Modified
261 | ```
262 |
263 | :::
264 |
265 | Which tells the webservers to not serve any Last-Modified headers, so browsers can only listen to the
266 | Cache-Control max-age header.
267 |
268 | These settings are used by us on lots of high-traffic websites, and disabling the ETag and Last-Modified
269 | headers have certainly helped to reduce traffic to a fifth of what it used to be. Especially Internet Explorer
270 | is very sensitive to those settings.
271 |
272 | The Yahoo Developer Network recommends turning off ETags because of this misbehavior:
273 | [Best practices for speeding up your web site - Disable ETags][disable-etags].
274 |
275 | Disabling Last-Modified will stop browsers from asking 304 Content Not Modified requests. In my
276 | experience this is positive, because the webserver has fewer requests to process, and browsers rely more
277 | on the Cache-Control settings you serve. But it may or may not suit you. Some browsers will try to
278 | validate assets every few minutes if you serve them a "Last-Modified" header, and that's why I would
279 | advise to disable the use of it completely.
280 |
281 | If you want more information about the headers we serve, consider using [REDbot.org][redbot] this will explain
282 | every header we serve, and why this is used. We also serve Cache-Control: public, this allows browsers to
283 | cache things even when accessing wsrv.nl over https://.
284 |
285 | Let us know if you need more info. We are open for comments about the caching policies we use. We do
286 | run complete tests on server load, bandwidth, and CPU-cycles, for each header we place. Enabling 304
287 | will generate 5 times more requests from browsers in our case, this could be different for your site, but I
288 | expect it to be the same.
289 |
290 | ## What if I still have a question?
291 |
292 | That means you're unique, and one of a kind! Did you also read our documentation?
293 |
294 | If your question is not within these frequently asked questions, or if there is still something not clear;
295 | [Please open an issue on our GitHub][weserv-issues]. We do our best to answer all questions, and we may even honor
296 | your question by featuring it on this page!
297 |
298 | [opendns-domain-tagging]: https://community.opendns.com/domaintagging/about/
299 | [weserv-github]: https://github.com/weserv/images/
300 | [weserv-issues]: https://github.com/weserv/images/issues
301 | [weserv-license]: https://github.com/weserv/images/blob/5.x/LICENSE
302 | [weserv-docker]: https://github.com/weserv/images/tree/5.x/docker#readme
303 | [weserv-privacy-policy]: https://github.com/weserv/images/blob/5.x/Privacy-Policy.md
304 | [cloudflare-network]: https://www.cloudflare.com/network/
305 | [ovh]: https://www.ovh.com/
306 | [scaleway]: https://www.scaleway.com/
307 | [hetzner]: https://www.hetzner.com/
308 | [ip-list]: /ips.txt
309 | [cloudflare]: https://www.cloudflare.com/
310 | [cloudflare-cdn]: https://www.cloudflare.com/cdn/
311 | [nginx-cache]: https://web.archive.org/web/20240404205848/https://www.nginx.com/blog/nginx-caching-guide/
312 | [cache-removal-tool]: https://github.com/weserv/images/issues/14
313 | [hsts]: https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
314 | [magick-formats]: https://imagemagick.org/script/formats.php#supported
315 | [n-pages]: /docs/format.md#number-of-pages
316 | [quality]: /docs/format.md#quality
317 | [nginx]: https://nginx.org/
318 | [cache-control]: /docs/format.md#cache-control
319 | [disable-etags]: https://developer.yahoo.com/performance/rules.html#etags
320 | [redbot]: https://redbot.org/
321 |
--------------------------------------------------------------------------------
/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: home
3 | title: wsrv.nl
4 | titleTemplate: wsrv.nl
5 | head:
6 | - - meta
7 | - name: twitter:title
8 | content: Image cache & resize service
9 | - - meta
10 | - name: twitter:description
11 | content: Manipulate images on-the-fly with a worldwide cache
12 | - - meta
13 | - property: og:title
14 | content: Image cache & resize service
15 | - - meta
16 | - property: og:description
17 | content: Manipulate images on-the-fly with a worldwide cache
18 | hero:
19 | image:
20 | light: /logo.svg
21 | dark: /logo-dark.svg
22 | name: wsrv.nl
23 | text: An image cache & resize service
24 | tagline: Manipulate images on-the-fly with a worldwide cache.
25 | actions:
26 | - theme: brand
27 | text: Read the documentation →
28 | link: /docs/introduction.html
29 | - theme: alt
30 | text: View on GitHub
31 | link: https://github.com/weserv/images
32 | features:
33 | - title: Crazy Fast
34 | icon:
35 | details: Performance is not just an afterthought, we baked it in from the start!
36 | - title: Awesome Technology
37 | icon:
38 | details: wsrv.nl employs best-in-class technologies such as nginx and libvips.
39 | - title: Free / Open Source
40 | icon:
41 | details: wsrv.nl is an open source project, so you can spend your money on other stuff.
42 | ---
43 |
44 | ### Your images unchained
45 |
46 |
47 |
55 |
56 |
57 | The CDN is provided by [Cloudflare](https://www.cloudflare.com/). Images are being cached and delivered straight from
58 | [300+ global datacenters](https://www.cloudflare.com/network/). This ensures the fastest load times and best performance.
59 |
60 | ### Widely used
61 |
62 | On average, we resize 6 million (6×106) images per hour, which generates around 400TB of outbound traffic per month.
63 |
64 | ### Features
65 |
66 |