diff --git a/main.js b/main.js index 8cf0c2c..a9233da 100644 --- a/main.js +++ b/main.js @@ -30,18 +30,17 @@ $(function() { i = 0; $("#start").on("click", function() { // Load the target and approximation images. - var targetPrefix = "/remote/img?url="; - var approxPrefix = "/approx/img?url="; - var imgUrl = $("#imgUrl").val(); + const targetPrefix = "/remote/img?url="; + const approxPrefix = "/approx/img?url="; + const imgUrl = $("#imgUrl").val(); $("#target-image").attr("src", targetPrefix + imgUrl).css("height", "auto").css("width", "auto"); $("#approx-image").attr("src", approxPrefix + imgUrl + "&" + i++).css("height", "auto").css("width", "auto"); console.log("Rendering", imgUrl); - var startTime = (new Date()).getTime(); + const startTime = (new Date()).getTime(); - // Once the target has loaded, we can check it's within the size limits. + // Once the target has loaded, we can display it $("#target-image").on("load", function() { - // If it is, show the images and stats. $("#error").text(""); $(this).show(); $("#approx-image").show(); @@ -55,5 +54,4 @@ $("#start").on("click", function() { console.log("Took " + Math.round(((new Date()).getTime()-startTime)/1000) + " seconds."); }); }); - }); diff --git a/server.go b/server.go index 51abed2..d47ee1c 100644 --- a/server.go +++ b/server.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "github.com/nfnt/resize" "image" _ "image/gif" _ "image/jpeg" @@ -61,13 +62,22 @@ func urlParam(r *http.Request) (string, error) { // This allows us to get around CORS issues. func remoteHandler(w http.ResponseWriter, r *http.Request) { img, err := getImg(r) + if err != nil { log.Println(err) w.Write([]byte(err.Error())) return } + defer img.Close() - io.Copy(w, img) + + _target, _, err := image.Decode(img) + + ci := make(chan image.Image) + go preprocessImage(_target, ci) + preprocessedImage := <-ci + + png.Encode(w, preprocessedImage) } // Serves the image generated by approximate() on the URL in the request. @@ -98,12 +108,12 @@ func approxHandler(w http.ResponseWriter, r *http.Request) { fmt.Println(err) return } - if dx, dy := _target.Bounds().Dx(), _target.Bounds().Dy(); dx > MAXSIZE || dy > MAXSIZE { - msg := fmt.Sprintf("Image of size %v.%v is too large (max size is %v)", dx, dy, MAXSIZE) - io.Copy(w, strings.NewReader(msg)) - } - target := toRGBA(_target) + ci := make(chan image.Image) + go preprocessImage(_target, ci) + preprocessedTarget := <-ci + + target := toRGBA(preprocessedTarget) approximation, score := approximate( target, @@ -120,6 +130,21 @@ func approxHandler(w http.ResponseWriter, r *http.Request) { }} } +func preprocessImage(image image.Image, cr chan image.Image) { + if dx, dy := image.Bounds().Dx(), image.Bounds().Dy(); dx > MAXSIZE || dy > MAXSIZE { + // Resample the image down to MAXSIZE + msg := fmt.Sprintf("Image of size %v.%v is too large (max size is %v). Downsampling.", dx, dy, MAXSIZE) + log.Println(msg) + + cr <- resize.Thumbnail(MAXSIZE, + MAXSIZE, + image, + resize.NearestNeighbor) + } else { + cr <- image + } +} + // Serve a static file. func fileHandler(w http.ResponseWriter, r *http.Request) { http.SetCookie(w, &http.Cookie{