Przeglądaj źródła

Add: thumbnail helper function

Dobrosław Żybort 11 lat temu
rodzic
commit
b744503c5c
2 zmienionych plików z 102 dodań i 0 usunięć
  1. 55
    0
      thumbnail.go
  2. 47
    0
      thumbnail_test.go

+ 55
- 0
thumbnail.go Wyświetl plik

@@ -0,0 +1,55 @@
1
+/*
2
+Copyright (c) 2012, Jan Schlicht <jan.schlicht@gmail.com>
3
+
4
+Permission to use, copy, modify, and/or distribute this software for any purpose
5
+with or without fee is hereby granted, provided that the above copyright notice
6
+and this permission notice appear in all copies.
7
+
8
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
10
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
12
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
13
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
14
+THIS SOFTWARE.
15
+*/
16
+
17
+package resize
18
+
19
+import (
20
+	"image"
21
+)
22
+
23
+// Thumbnail will downscale provided image to max width and height preserving
24
+// original aspect ratio and using the interpolation function interp.
25
+// It will return original image, without processing it, if original sizes
26
+// are already smaller than provided constraints.
27
+func Thumbnail(maxWidth, maxHeight uint, img image.Image, interp InterpolationFunction) image.Image {
28
+	origBounds := img.Bounds()
29
+	origWidth := uint(origBounds.Dx())
30
+	origHeight := uint(origBounds.Dy())
31
+	newWidth, newHeight := origWidth, origHeight
32
+
33
+	// Return original image if it have same or smaller size as constraints
34
+	if maxWidth >= origWidth && maxHeight >= origHeight {
35
+		return img
36
+	}
37
+
38
+	// Preserve aspect ratio
39
+	if origWidth > maxWidth {
40
+		newHeight = uint(origHeight * maxWidth / origWidth)
41
+		if newHeight < 1 {
42
+			newHeight = 1
43
+		}
44
+		newWidth = maxWidth
45
+	}
46
+
47
+	if newHeight > maxHeight {
48
+		newWidth = uint(newWidth * maxHeight / newHeight)
49
+		if newWidth < 1 {
50
+			newWidth = 1
51
+		}
52
+		newHeight = maxHeight
53
+	}
54
+	return Resize(newWidth, newHeight, img, interp)
55
+}

+ 47
- 0
thumbnail_test.go Wyświetl plik

@@ -0,0 +1,47 @@
1
+package resize
2
+
3
+import (
4
+	"image"
5
+	"runtime"
6
+	"testing"
7
+)
8
+
9
+func init() {
10
+	runtime.GOMAXPROCS(runtime.NumCPU())
11
+}
12
+
13
+var thumbnailTests = []struct {
14
+	origWidth      int
15
+	origHeight     int
16
+	maxWidth       uint
17
+	maxHeight      uint
18
+	expectedWidth  uint
19
+	expectedHeight uint
20
+}{
21
+	{5, 5, 10, 10, 5, 5},
22
+	{10, 10, 5, 5, 5, 5},
23
+	{10, 50, 10, 10, 2, 10},
24
+	{50, 10, 10, 10, 10, 2},
25
+	{50, 100, 60, 90, 45, 90},
26
+	{120, 100, 60, 90, 60, 50},
27
+	{200, 250, 200, 150, 120, 150},
28
+}
29
+
30
+func TestThumbnail(t *testing.T) {
31
+	for i, tt := range thumbnailTests {
32
+		img := image.NewGray16(image.Rect(0, 0, tt.origWidth, tt.origHeight))
33
+
34
+		outImg := Thumbnail(tt.maxWidth, tt.maxHeight, img, NearestNeighbor)
35
+
36
+		newWidth := uint(outImg.Bounds().Dx())
37
+		newHeight := uint(outImg.Bounds().Dy())
38
+		if newWidth != tt.expectedWidth ||
39
+			newHeight != tt.expectedHeight {
40
+			t.Errorf("%d. Thumbnail(%v, %v, img, NearestNeighbor) => "+
41
+				"width: %v, height: %v, want width: %v, height: %v",
42
+				i, tt.maxWidth, tt.maxHeight,
43
+				newWidth, newHeight, tt.expectedWidth, tt.expectedHeight,
44
+			)
45
+		}
46
+	}
47
+}