-
Notifications
You must be signed in to change notification settings - Fork 9
/
fan_out_channel.go
90 lines (81 loc) · 2.62 KB
/
fan_out_channel.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package main
import (
"bytes"
"encoding/base64"
"fmt"
"html/template"
"image"
"image/draw"
"image/jpeg"
"net/http"
"os"
"strconv"
"time"
)
// fan-out with individual channels //////////////////////////////////////////
func cutWithChannel(original image.Image, db *map[string][3]float64, tileSize, x1, y1, x2, y2 int) <-chan string {
c := make(chan string)
go func() {
newimage := image.NewNRGBA(image.Rect(x1, y1, x2, y2))
sp := image.Point{0, 0}
for y := y1; y < y2; y = y + tileSize {
for x := x1; x < x2; x = x + tileSize {
// get the RGBA value
r, g, b, _ := original.At(x, y).RGBA()
color := [3]float64{float64(r), float64(g), float64(b)}
nearest := nearest(color, db)
file, err := os.Open(nearest)
if err == nil {
img, _, err := image.Decode(file)
if err == nil {
t := resize(img, tileSize)
tile := t.SubImage(t.Bounds())
tileBounds := image.Rect(x, y, x+tileSize, y+tileSize)
draw.Draw(newimage, tileBounds, tile, sp, draw.Src)
} else {
fmt.Println("error in decoding nearest", err, nearest)
}
} else {
fmt.Println("error opening file when creating mosaic:", nearest)
}
file.Close()
}
}
buf2 := new(bytes.Buffer)
jpeg.Encode(buf2, newimage, nil)
c <- base64.StdEncoding.EncodeToString(buf2.Bytes())
}()
return c
}
// Handler function for fan-out with individual channels
func fanOutWithChannelHandlerFunc(w http.ResponseWriter, r *http.Request) {
t0 := time.Now()
// get the content from the POSTed form
r.ParseMultipartForm(10485760) // max body in memory is 10MB
file, _, _ := r.FormFile("image")
defer file.Close()
tileSize, _ := strconv.Atoi(r.FormValue("tile_size"))
//
// // decode and get original image
original, _, _ := image.Decode(file)
bounds := original.Bounds()
db := cloneTilesDB()
c1 := cutWithChannel(original, &db, tileSize, bounds.Min.X, bounds.Min.Y, bounds.Max.X/2, bounds.Max.Y/2)
c2 := cutWithChannel(original, &db, tileSize, bounds.Max.X/2, bounds.Min.Y, bounds.Max.X, bounds.Max.Y/2)
c3 := cutWithChannel(original, &db, tileSize, bounds.Min.X, bounds.Max.Y/2, bounds.Max.X/2, bounds.Max.Y)
c4 := cutWithChannel(original, &db, tileSize, bounds.Max.X/2, bounds.Max.Y/2, bounds.Max.X, bounds.Max.Y)
buf1 := new(bytes.Buffer)
jpeg.Encode(buf1, original, nil)
originalStr := base64.StdEncoding.EncodeToString(buf1.Bytes())
t1 := time.Now()
images := map[string]string{
"original": originalStr,
"part1": <-c1,
"part2": <-c2,
"part3": <-c3,
"part4": <-c4,
"duration": fmt.Sprintf("%v ", t1.Sub(t0)),
}
t, _ := template.ParseFiles("results_parts.html")
t.Execute(w, images)
}