1# bild
2
3![bild logo](assets/img/logo.png)
4
5[![MIT License](https://img.shields.io/github/license/mashape/apistatus.svg?maxAge=2592000)](https://github.com/anthonynsimon/bild/blob/master/LICENSE)
6[![GoDoc](https://godoc.org/github.com/anthonynsimon/bild?status.svg)](https://godoc.org/github.com/anthonynsimon/bild)
7[![CircleCI](https://circleci.com/gh/anthonynsimon/bild/tree/master.svg?style=svg)](https://circleci.com/gh/anthonynsimon/bild/tree/master)
8[![Go Report Card](https://goreportcard.com/badge/github.com/anthonynsimon/bild)](https://goreportcard.com/report/github.com/anthonynsimon/bild)
9
10A collection of parallel image processing algorithms in pure Go.
11
12The aim of this project is simplicity in use and development over absolute high performance, but most algorithms are designed to be efficient and make use of parallelism when available.
13
14It uses packages from the standard library whenever possible to reduce dependency use and development abstractions.
15
16All operations return image types from the standard library.
17
18## Documentation
19The documentation for the various packages is available [here](https://pkg.go.dev/mod/github.com/anthonynsimon/bild?tab=packages).
20
21
22## CLI usage
23
24Download and compile from sources:
25```
26go get github.com/anthonynsimon/bild
27```
28
29Or get the pre-compiled binaries for your platform on the [releases page](https://github.com/anthonynsimon/bild/releases)
30
31
32```
33bild
34
35A collection of parallel image processing algorithms in pure Go
36
37Usage:
38  bild [command]
39
40Available Commands:
41  adjust      adjust basic image features like brightness or contrast
42  blend       blend two images together
43  blur        blur an image using the specified method
44  channel     channel operations on images
45  effect      apply effects on images
46  help        Help about any command
47  histogram   histogram operations on images
48  imgio       i/o operations on images
49  noise       noise generators
50  segment     segment an image using the specified method
51
52Flags:
53  -h, --help      help for bild
54      --version   version for bild
55
56Use "bild [command] --help" for more information about a command.
57```
58
59For example, to apply a median effect with a radius of 1.5 on the image `input.png`, writing the result into a new file called `output.png`:
60```
61bild effect median --radius 1.5 input.png output.png
62```
63
64
65## Install package
66
67bild requires Go version 1.11 or greater.
68
69```bash
70go get github.com/anthonynsimon/bild/...
71```
72
73## Basic package usage example:
74```go
75package main
76
77import (
78    "github.com/anthonynsimon/bild/effect"
79    "github.com/anthonynsimon/bild/imgio"
80    "github.com/anthonynsimon/bild/transform"
81)
82
83func main() {
84    img, err := imgio.Open("input.jpg")
85    if err != nil {
86        fmt.Println(err)
87        return
88    }
89
90    inverted := effect.Invert(img)
91    resized := transform.Resize(inverted, 800, 800, transform.Linear)
92    rotated := transform.Rotate(resized, 45, nil)
93
94    if err := imgio.Save("output.png", rotated, imgio.PNGEncoder()); err != nil {
95        fmt.Println(err)
96        return
97    }
98}
99```
100
101# Output examples
102## Adjustment
103    import "github.com/anthonynsimon/bild/adjust"
104
105### Brightness
106    result := adjust.Brightness(img, 0.25)
107
108![example](assets/img/brightness.jpg)
109
110### Contrast
111    result := adjust.Contrast(img, -0.5)
112
113![example](assets/img/contrast.jpg)
114
115### Gamma
116    result := adjust.Gamma(img, 2.2)
117
118![example](assets/img/gamma.jpg)
119
120
121### Hue
122    result := adjust.Hue(img, -42)
123
124![example](assets/img/hue.jpg)
125
126### Saturation
127    result := adjust.Saturation(img, 0.5)
128
129![example](assets/img/saturation.jpg)
130
131
132
133## Blend modes
134    import "github.com/anthonynsimon/bild/blend"
135
136    result := blend.Multiply(bg, fg)
137
138| Add | Color Burn | Color Dodge |
139| :----------: | :---------: | :------: |
140| ![](assets/img/add.jpg) | ![](assets/img/colorburn.jpg) | ![](assets/img/colordodge.jpg) |
141| **Darken** | **Difference** | **Divide** |
142| ![](assets/img/darken.jpg) | ![](assets/img/difference.jpg) | ![](assets/img/divide.jpg) |
143| **Exclusion** | **Lighten** | **Linear Burn** |
144| ![](assets/img/exclusion.jpg) | ![](assets/img/lighten.jpg) | ![](assets/img/linearburn.jpg) |
145| **Linear Light** | **Multiply** | **Normal** |
146| ![](assets/img/linearlight.jpg) | ![](assets/img/multiply.jpg) | ![](assets/img/normal.jpg) |
147| **Opacity** | **Overlay** | **Screen** |
148| ![](assets/img/opacity.jpg) | ![](assets/img/overlay.jpg) | ![](assets/img/screen.jpg) |
149| **Soft Light** | **Subtract** | |
150| ![](assets/img/softlight.jpg) | ![](assets/img/subtract.jpg) | |
151
152
153## Blur
154    import "github.com/anthonynsimon/bild/blur"
155
156### Box Blur
157    result := blur.Box(img, 3.0)
158
159![example](assets/img/boxblur.jpg)
160
161
162### Gaussian Blur
163    result := blur.Gaussian(img, 3.0)
164
165
166![example](assets/img/gaussianblur.jpg)
167
168
169## Channel
170    import "github.com/anthonynsimon/bild/channel"
171
172### Extract Channels
173    result := channel.Extract(img, channel.Alpha)
174
175![example](assets/img/extractchannel.jpg)
176
177### Extract Multiple Channels
178    result := channel.ExtractMultiple(img, channel.Red, channel.Alpha)
179
180## Effect
181    import "github.com/anthonynsimon/bild/effect"
182
183### Dilate
184    result := effect.Dilate(img, 3)
185
186![example](assets/img/dilate.jpg)
187
188### Edge Detection
189    result := effect.EdgeDetection(img, 1.0)
190
191![example](assets/img/edgedetection.jpg)
192
193### Emboss
194    result := effect.Emboss(img)
195
196![example](assets/img/emboss.jpg)
197
198### Erode
199    result := effect.Erode(img, 3)
200
201![example](assets/img/erode.jpg)
202
203### Grayscale
204    result := effect.Grayscale(img)
205
206![example](assets/img/grayscale.jpg)
207
208### Invert
209    result := effect.Invert(img)
210
211![example](assets/img/invert.jpg)
212
213### Median
214    result := effect.Median(img, 10.0)
215
216![example](assets/img/median.jpg)
217
218### Sepia
219    result := effect.Sepia(img)
220
221![example](assets/img/sepia.jpg)
222
223### Sharpen
224    result := effect.Sharpen(img)
225
226![example](assets/img/sharpen.jpg)
227
228### Sobel
229    result := effect.Sobel(img)
230
231![example](assets/img/sobel.jpg)
232
233### Unsharp Mask
234    result := effect.UnsharpMask(img, 0.6, 1.2)
235
236![example](assets/img/unsharpmask.jpg)
237
238
239## Histogram
240    import "github.com/anthonynsimon/bild/histogram"
241
242### RGBA Histogram
243    hist := histogram.NewRGBAHistogram(img)
244    result := hist.Image()
245
246![example](assets/img/histogram.png)
247
248
249## Noise
250    import "github.com/anthonynsimon/bild/noise"
251
252### Uniform colored
253    result := noise.Generate(280, 280, &noise.Options{Monochrome: false, NoiseFn: noise.Uniform})
254
255![example](assets/img/noiseuniform.jpg)
256
257
258### Binary monochrome
259    result := noise.Generate(280, 280, &noise.Options{Monochrome: true, NoiseFn: noise.Binary})
260
261![example](assets/img/noisebinary.jpg)
262
263
264### Gaussian monochrome
265    result := noise.Generate(280, 280, &noise.Options{Monochrome: true, NoiseFn: noise.Gaussian})
266
267![example](assets/img/noisegaussian.jpg)
268
269### Perlin Noise
270    result := noise.GeneratePerlin(280, 280, 0.25)
271![example](assets/img/perlin.jpg)
272
273## Paint
274    import "github.com/anthonynsimon/bild/paint"
275
276### Flood Fill
277    // Fuzz is the percentage of maximum color distance that is tolerated
278    result := paint.FloodFill(img, image.Point{240, 0}, color.RGBA{255, 0, 0, 255}, 15)
279
280![example](assets/img/floodfill.jpg)
281
282
283## Segmentation
284    import "github.com/anthonynsimon/bild/segment"
285
286### Threshold
287    result := segment.Threshold(img, 128)
288
289![example](assets/img/threshold.jpg)
290
291
292## Transform
293    import "github.com/anthonynsimon/bild/transform"
294
295### Crop
296    // Source image is 280x280
297    result := transform.Crop(img, image.Rect(70,70,210,210))
298
299![example](assets/img/crop.jpg)
300
301### FlipH
302    result := transform.FlipH(img)
303
304![example](assets/img/fliph.jpg)
305
306### FlipV
307    result := transform.FlipV(img)
308
309![example](assets/img/flipv.jpg)
310
311
312### Resize Resampling Filters
313    result := transform.Resize(img, 280, 280, transform.Linear)
314
315| Nearest Neighbor | Linear | Gaussian |
316|:----------: | :---------: | :------: |
317| ![](assets/img/resizenearestneighbor.jpg) | ![](assets/img/resizelinear.jpg) | ![](assets/img/resizegaussian.jpg) |
318| **Mitchell Netravali** | **Catmull Rom** | **Lanczos** |
319| ![](assets/img/resizemitchell.jpg) | ![](assets/img/resizecatmullrom.jpg) | ![](assets/img/resizelanczos.jpg) |
320
321
322### Rotate
323    // Options set to nil will use defaults (ResizeBounds set to false, Pivot at center)
324    result := transform.Rotate(img, -45.0, nil)
325
326![example](assets/img/rotation03.gif)
327
328    // If ResizeBounds is set to true, the full rotation bounding area is used
329    result := transform.Rotate(img, -45.0, &transform.RotationOptions{ResizeBounds: true})
330
331![example](assets/img/rotation01.gif)
332
333    // Pivot coordinates are set from the top-left corner
334    // Notice ResizeBounds being set to default (false)
335    result := transform.Rotate(img, -45.0, &transform.RotationOptions{Pivot: &image.Point{0, 0}})
336
337![example](assets/img/rotation02.gif)
338
339### Shear Horizontal
340    result := transform.ShearH(img, 30)
341
342![example](assets/img/shearh.jpg)
343
344### Shear Vertical
345    result := transform.ShearV(img, 30)
346
347![example](assets/img/shearv.jpg)
348
349### Translate
350    result := transform.Translate(img, 80, 0)
351
352![example](assets/img/translate.jpg)
353
354
355## Contribute
356
357Want to hack on the project? Any kind of contribution is welcome!
358Simply follow the next steps:
359
360- Fork the project.
361- Create a new branch.
362- Make your changes and write tests when practical.
363- Commit your changes to the new branch.
364- Send a pull request, it will be reviewed shortly.
365
366In case you want to add a feature, please create a new issue and briefly explain what the feature would consist of.
367For bugs or requests, before creating an issue please check if one has already been created for it.
368
369
370## Changelog
371
372Please see the [changelog](CHANGELOG.md) for more details.
373
374## License
375
376This project is licensed under the MIT license. Please read the LICENSE file.
377