-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Leon Wolf
committed
Jan 28, 2020
1 parent
a7b2d8c
commit 9d58433
Showing
5 changed files
with
243 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,5 @@ | |
|
||
# Dependency directories (remove the comment below to include it) | ||
# vendor/ | ||
|
||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,151 @@ | ||
# canvas | ||
A simple go library for transforming images using mostly native go functionalitys | ||
# This package is no longer being updated! Please look for alternatives if that bothers you. | ||
|
||
Resize | ||
====== | ||
|
||
Image resizing for the [Go programming language](http://golang.org) with common interpolation methods. | ||
|
||
[](https://travis-ci.org/nfnt/resize) | ||
|
||
Installation | ||
------------ | ||
|
||
```bash | ||
$ go get github.com/nfnt/resize | ||
``` | ||
|
||
It's that easy! | ||
|
||
Usage | ||
----- | ||
|
||
This package needs at least Go 1.1. Import package with | ||
|
||
```go | ||
import "github.com/nfnt/resize" | ||
``` | ||
|
||
The resize package provides 2 functions: | ||
|
||
* `resize.Resize` creates a scaled image with new dimensions (`width`, `height`) using the interpolation function `interp`. | ||
If either `width` or `height` is set to 0, it will be set to an aspect ratio preserving value. | ||
* `resize.Thumbnail` downscales an image preserving its aspect ratio to the maximum dimensions (`maxWidth`, `maxHeight`). | ||
It will return the original image if original sizes are smaller than the provided dimensions. | ||
|
||
```go | ||
resize.Resize(width, height uint, img image.Image, interp resize.InterpolationFunction) image.Image | ||
resize.Thumbnail(maxWidth, maxHeight uint, img image.Image, interp resize.InterpolationFunction) image.Image | ||
``` | ||
|
||
The provided interpolation functions are (from fast to slow execution time) | ||
|
||
- `NearestNeighbor`: [Nearest-neighbor interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) | ||
- `Bilinear`: [Bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation) | ||
- `Bicubic`: [Bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation) | ||
- `MitchellNetravali`: [Mitchell-Netravali interpolation](http://dl.acm.org/citation.cfm?id=378514) | ||
- `Lanczos2`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=2 | ||
- `Lanczos3`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=3 | ||
|
||
Which of these methods gives the best results depends on your use case. | ||
|
||
Sample usage: | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"github.com/nfnt/resize" | ||
"image/jpeg" | ||
"log" | ||
"os" | ||
) | ||
|
||
func main() { | ||
// open "test.jpg" | ||
file, err := os.Open("test.jpg") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// decode jpeg into image.Image | ||
img, err := jpeg.Decode(file) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
file.Close() | ||
|
||
// resize to width 1000 using Lanczos resampling | ||
// and preserve aspect ratio | ||
m := resize.Resize(1000, 0, img, resize.Lanczos3) | ||
|
||
out, err := os.Create("test_resized.jpg") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
defer out.Close() | ||
|
||
// write new image to file | ||
jpeg.Encode(out, m, nil) | ||
} | ||
``` | ||
|
||
Caveats | ||
------- | ||
|
||
* Optimized access routines are used for `image.RGBA`, `image.NRGBA`, `image.RGBA64`, `image.NRGBA64`, `image.YCbCr`, `image.Gray`, and `image.Gray16` types. All other image types are accessed in a generic way that will result in slow processing speed. | ||
* JPEG images are stored in `image.YCbCr`. This image format stores data in a way that will decrease processing speed. A resize may be up to 2 times slower than with `image.RGBA`. | ||
|
||
|
||
Downsizing Samples | ||
------- | ||
|
||
Downsizing is not as simple as it might look like. Images have to be filtered before they are scaled down, otherwise aliasing might occur. | ||
Filtering is highly subjective: Applying too much will blur the whole image, too little will make aliasing become apparent. | ||
Resize tries to provide sane defaults that should suffice in most cases. | ||
|
||
### Artificial sample | ||
|
||
Original image | ||
 | ||
|
||
<table> | ||
<tr> | ||
<th><img src="http://nfnt.github.com/img/rings_300_NearestNeighbor.png" /><br>Nearest-Neighbor</th> | ||
<th><img src="http://nfnt.github.com/img/rings_300_Bilinear.png" /><br>Bilinear</th> | ||
</tr> | ||
<tr> | ||
<th><img src="http://nfnt.github.com/img/rings_300_Bicubic.png" /><br>Bicubic</th> | ||
<th><img src="http://nfnt.github.com/img/rings_300_MitchellNetravali.png" /><br>Mitchell-Netravali</th> | ||
</tr> | ||
<tr> | ||
<th><img src="http://nfnt.github.com/img/rings_300_Lanczos2.png" /><br>Lanczos2</th> | ||
<th><img src="http://nfnt.github.com/img/rings_300_Lanczos3.png" /><br>Lanczos3</th> | ||
</tr> | ||
</table> | ||
|
||
### Real-Life sample | ||
|
||
Original image | ||
 | ||
|
||
<table> | ||
<tr> | ||
<th><img src="http://nfnt.github.com/img/IMG_3694_300_NearestNeighbor.png" /><br>Nearest-Neighbor</th> | ||
<th><img src="http://nfnt.github.com/img/IMG_3694_300_Bilinear.png" /><br>Bilinear</th> | ||
</tr> | ||
<tr> | ||
<th><img src="http://nfnt.github.com/img/IMG_3694_300_Bicubic.png" /><br>Bicubic</th> | ||
<th><img src="http://nfnt.github.com/img/IMG_3694_300_MitchellNetravali.png" /><br>Mitchell-Netravali</th> | ||
</tr> | ||
<tr> | ||
<th><img src="http://nfnt.github.com/img/IMG_3694_300_Lanczos2.png" /><br>Lanczos2</th> | ||
<th><img src="http://nfnt.github.com/img/IMG_3694_300_Lanczos3.png" /><br>Lanczos3</th> | ||
</tr> | ||
</table> | ||
|
||
|
||
License | ||
------- | ||
|
||
Copyright (c) 2012 Jan Schlicht <[email protected]> | ||
Resize is released under a MIT style license. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package canvas | ||
|
||
import ( | ||
"golang.org/x/image/draw" | ||
"image" | ||
) | ||
|
||
type InterpolationFunction int | ||
|
||
// InterpolationFunction constants | ||
const ( | ||
Bilinear InterpolationFunction = iota | ||
CatmullRom | ||
) | ||
|
||
// kernal, returns an InterpolationFunctions taps and kernel. | ||
func (i InterpolationFunction) kernel() *draw.Kernel { | ||
switch i { | ||
case Bilinear: | ||
return draw.BiLinear | ||
case CatmullRom: | ||
return draw.CatmullRom | ||
default: | ||
return draw.CatmullRom | ||
} | ||
} | ||
|
||
func Resize(img image.Image, width int, height int, intFunc InterpolationFunction) (image.Image, error) { | ||
|
||
if width == 0 && height == 0 { | ||
width = img.Bounds().Dx() | ||
height = img.Bounds().Dy() | ||
} else if width == 0 && height != 0 { | ||
width = img.Bounds().Dx() / img.Bounds().Dy() * height | ||
} else if width != 0 && height == 0 { | ||
height = img.Bounds().Dy() / img.Bounds().Dx() * width | ||
} | ||
// new size of image | ||
dstRect := image.Rect(0, 0, width, height) | ||
// perform resizing | ||
dstImg := image.NewRGBA(dstRect) | ||
intFunc.kernel().Scale(dstImg, dstRect, img, img.Bounds(), draw.Over, nil) | ||
|
||
return dstImg, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package canvas | ||
|
||
import ( | ||
"image" | ||
"image/color" | ||
"log" | ||
"runtime" | ||
"testing" | ||
) | ||
|
||
var img = image.NewNRGBA(image.Rect(0, 0, 5, 5)) | ||
|
||
func init() { | ||
runtime.GOMAXPROCS(runtime.NumCPU()) | ||
img.Set(5, 5, color.Black) | ||
} | ||
|
||
func Test_SameSize(t *testing.T) { | ||
newImg, _ := Resize(img, 0, 0, CatmullRom) | ||
if newImg.Bounds() != img.Bounds() { | ||
log.Print(img.Bounds().Dx(), "x", img.Bounds().Dy()) | ||
log.Print(newImg.Bounds().Dx(), "x", newImg.Bounds().Dy()) | ||
t.Fail() | ||
} | ||
} | ||
|
||
func Test_Height(t *testing.T) { | ||
newImg, err := Resize(img, 0, 100, CatmullRom) | ||
if err != nil || newImg.Bounds().Dy() != 100 || newImg.Bounds().Dx() != 100 { | ||
t.Fail() | ||
} | ||
} | ||
func Test_Width(t *testing.T) { | ||
newImg, err := Resize(img, 200, 0, CatmullRom) | ||
if err != nil || newImg.Bounds().Dy() != 200 || newImg.Bounds().Dx() != 200 { | ||
t.Fail() | ||
} | ||
} | ||
func Test_WidthAndHeight(t *testing.T) { | ||
newImg, err := Resize(img, 300, 300, CatmullRom) | ||
if err != nil || newImg.Bounds() != image.Rect(0, 0, 300, 300) { | ||
t.Fail() | ||
} | ||
} |