func (fi *FileInfo) CreateThumbnail(r io.Reader, c appengine.Context) (data []byte, err os.Error) { defer func() { if rec := recover(); rec != nil { log.Println(rec) // 1x1 pixel transparent GIf, bas64 encoded: s := "R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data, _ = base64.StdEncoding.DecodeString(s) fi.ThumbnailUrl = "data:image/gif;base64," + s } memcache.Add(c, &memcache.Item{ Key: string(fi.Key), Value: data, Expiration: EXPIRATION_TIME, }) }() img, _, err := image.Decode(r) check(err) if bounds := img.Bounds(); bounds.Dx() > THUMBNAIL_MAX_WIDTH || bounds.Dy() > THUMBNAIL_MAX_HEIGHT { w, h := THUMBNAIL_MAX_WIDTH, THUMBNAIL_MAX_HEIGHT if bounds.Dx() > bounds.Dy() { h = bounds.Dy() * h / bounds.Dx() } else { w = bounds.Dx() * w / bounds.Dy() } img = resize.Resize(img, img.Bounds(), w, h) } var b bytes.Buffer err = png.Encode(&b, img) check(err) data = b.Bytes() fi.ThumbnailUrl = "data:image/png;base64," + base64.StdEncoding.EncodeToString(data) return }
// upload is the HTTP handler for uploading images; it handles "/". func upload(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { // No upload; show the upload form. templates.ExecuteTemplate(w, "upload.html", nil) return } f, _, err := r.FormFile("image") check(err) defer f.Close() // Grab the image data var buf bytes.Buffer io.Copy(&buf, f) i, _, err := image.Decode(&buf) check(err) // Resize if too large, for more efficient moustachioing. // We aim for less than 1200 pixels in any dimension; if the // picture is larger than that, we squeeze it down to 600. const max = 1200 if b := i.Bounds(); b.Dx() > max || b.Dy() > max { // If it's gigantic, it's more efficient to downsample first // and then resize; resizing will smooth out the roughness. if b.Dx() > 2*max || b.Dy() > 2*max { w, h := max, max if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resample(i, i.Bounds(), w, h) b = i.Bounds() } w, h := max/2, max/2 if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resize(i, i.Bounds(), w, h) } // Encode as a new JPEG image. buf.Reset() err = jpeg.Encode(&buf, i, nil) check(err) // Create an App Engine context for the client's request. c := appengine.NewContext(r) // Save the image under a unique key, a hash of the image. key := datastore.NewKey(c, "Image", keyOf(buf.Bytes()), 0, nil) _, err = datastore.Put(c, key, &Image{buf.Bytes()}) check(err) // Redirect to /edit using the key. http.Redirect(w, r, "/edit?id="+key.StringID(), http.StatusFound) }
func handler(w http.ResponseWriter, r *http.Request) { get := func(n string) int { i, _ := strconv.Atoi(r.FormValue(n)) return i } myurl := "https://s3.amazonaws.com/lenses_s3/uploads/IMG_1762.JPG" res, err := http.Get(myurl) if err != nil { log.Fatal(err) } img, err := ioutil.ReadAll(res.Body) if err != nil { log.Fatal(err) } res.Body.Close() rdr := bytes.NewReader(img) i, _, err := image.Decode(rdr) check(err) // Resize if too large, for more efficient moustachioing. // We aim for less than 1200 pixels in any dimension; if the // picture is larger than that, we squeeze it down to 600. max := 0 if x := get("x"); x != 0 { max = x } else { max = 1200 } if b := i.Bounds(); b.Dx() > max || b.Dy() > max { // If it's gigantic, it's more efficient to downsample first // and then resize; resizing will smooth out the roughness. if b.Dx() > 2*max || b.Dy() > 2*max { w, h := max, max if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resample(i, i.Bounds(), w, h) b = i.Bounds() } w, h := max/2, max/2 if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resize(i, i.Bounds(), w, h) } // Deliver image w.Header().Set("Content-type", "image/jpeg") jpeg.Encode(w, i, nil) }
// Proportional image resize to max size by any side func resizeImage(i image.Image, max int) image.Image { if b := i.Bounds(); b.Dx() > max || b.Dy() > max { w, h := max, max if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resize(i, i.Bounds(), w, h) } return i }
// 99.9% of this was stolen from // http://goo.gl/lgkTC func extractImageFromPost(name string, r *http.Request) []byte { f, _, err := r.FormFile(name) check(err) defer f.Close() // Grab the image data buf := new(bytes.Buffer) io.Copy(buf, f) i, _, err := image.Decode(buf) check(err) // We aim for less than 400 pixels in any dimension; if the // picture is larger than that, we squeeze it down const max = 800 if b := i.Bounds(); b.Dx() > max || b.Dy() > max { // If it's gigantic, it's more efficient to downsample first // and then resize; resizing will smooth out the roughness. if b.Dx() > 2*max || b.Dy() > 2*max { w, h := max, max if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resample(i, i.Bounds(), w, h) b = i.Bounds() } w, h := max/2, max/2 //w, h := max, max if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resize(i, i.Bounds(), w, h) } // Encode as a new JPEG image. buf.Reset() err = jpeg.Encode(buf, i, &jpeg.Options{Quality: 95}) check(err) // return JPEG return buf.Bytes() }
func scale(i image.Image) image.Image { return resize.Resize(i, i.Bounds(), 320, 240) }
// upload is the HTTP handler for uploading images; it handles "/". func upload(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) var imgprops appimage.ServingURLOptions imgprops.Secure = true imgprops.Size = 180 imgprops.Crop = false if s, ok := sess.IsSess(w, r, c); ok { u, _ := model.GetCta(c, s.User) emp, err := u.GetEmpresa(c, r.FormValue("IdEmp")) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } imgo := model.GetLogo(c, r.FormValue("IdEmp")) if imgo == nil { imgo = new(model.Image) imgo.IdEmp = emp.IdEmp } fd := imgToForm(*imgo) tc := make(map[string]interface{}) tc["Sess"] = s tc["Empresa"] = emp tc["FormData"] = fd if r.Method != "POST" { // No upload; show the upload form. micrositio(w, r) return } idemp := r.FormValue("IdEmp") sp1 := r.FormValue("Sp1") sp2 := r.FormValue("Sp2") f, _, err := r.FormFile("image") model.Check(err) defer f.Close() // Grab the image data var buf bytes.Buffer io.Copy(&buf, f) i, _, err := image.Decode(&buf) if err != nil { if r.FormValue("tipo") == "async" { //w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, "<p>'%s'</p>", "No se actualizó el logotipo, formato no aceptado") } else { tc["Error"] = struct{ Badformat string }{"badformat"} micrositioTpl.Execute(w, tc) } return } const max = 600 // We aim for less than max pixels in any dimension. if b := i.Bounds(); b.Dx() > max || b.Dy() > max { // If it's gigantic, it's more efficient to downsample first // and then resize; resizing will smooth out the roughness. if b.Dx() > 2*max || b.Dy() > 2*max { w, h := max*2, max*2 if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resample(i, i.Bounds(), w, h) b = i.Bounds() } w, h := max, max if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resize(i, i.Bounds(), w, h) } // Encode as a new JPEG image. buf.Reset() err = jpeg.Encode(&buf, i, nil) if err != nil { if r.FormValue("tipo") == "async" { fmt.Fprintf(w, "<p>'%s'</p>", "No se actualizó el logotipo, formato no aceptado") } else { tc["Error"] = struct{ Badencode string }{"badencode"} micrositioTpl.Execute(w, tc) } return } var blobkey appengine.BlobKey blob, err := blobstore.Create(c, "image/jpeg") if err != nil { c.Errorf("blobstore Create: %v", idemp) } _, err = blob.Write(buf.Bytes()) if err != nil { c.Errorf("blobstore Write: %v", idemp) } err = blob.Close() if err != nil { c.Errorf("blobstore Close: %v", idemp) } blobkey, err = blob.Key() if err != nil { c.Errorf("blobstore Key Gen: %v", idemp) } if url, err := appimage.ServingURL(c, blobkey, &imgprops); err != nil { c.Errorf("Cannot construct EmpLogo ServingURL : %v", idemp) } else { // Save the image under a unique key, a hash of the image. img := &model.Image{ Data: buf.Bytes(), IdEmp: idemp, IdImg: model.RandId(20), Kind: "EmpLogo", Name: imgo.Name, Desc: imgo.Desc, Sizepx: 0, Sizepy: 0, Url: imgo.Url, Type: "", Sp1: sp1, Sp2: sp2, Sp3: string(blobkey), Sp4: url.String(), Np1: 0, Np2: 0, Np3: 0, Np4: 0, } _, err = model.PutLogo(c, img) if err != nil { if r.FormValue("tipo") == "async" { fmt.Fprintf(w, "<p>'%s'</p>", "No se actualizó el logotipo. Sistema en matenimiento, intente en unos minutos") } else { tc["Error"] = struct{ Cantsave string }{"cantsave"} micrositioTpl.Execute(w, tc) } return } } /* se crea icono */ val := slogores(c, idemp, 70, 0) if val != 0 { tc["Error"] = struct{ Cantsave string }{"cantsave"} micrositioTpl.Execute(w, tc) return } if r.FormValue("tipo") == "async" { fmt.Fprintf(w, "<p></p>") } else { micrositio(w, r) } return } else { http.Redirect(w, r, "/r/registro", http.StatusFound) } }
// Resize only if picture from EmpLogo is more than 80 pix width // If resize, save image to entity king ShortLogo and stream // If no resize is necesary, save to entity ShortLogo and stream func rslogo(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) if r.Method == "GET" { sf, _ := strconv.Atoi(r.FormValue("s")) force, _ := strconv.Atoi(r.FormValue("force")) // Check for shortlogo var simg model.Image simg.Kind = "ShortLogo" if r.FormValue("IdEmp") != "" { simg.IdEmp = r.FormValue("IdEmp") } else { w.WriteHeader(http.StatusNotFound) return } if force != 1 { shortlogo, _ := model.GetShortLogo(c, r.FormValue("IdEmp")) // Stream short logo if already exists if shortlogo != nil { w.Header().Set("Content-type", "image/jpeg") w.Write(shortlogo.Data) /* m, _, err := image.Decode(bytes.NewBuffer(shortlogo.Data)) model.Check(err) w.Header().Set("Content-type", "image/jpeg") jpeg.Encode(w, m, nil) */ return } } // Process biglogo if shortlogo doesn't exists // Save and Stream new shortlogo biglogo := model.GetLogo(c, r.FormValue("IdEmp")) if biglogo == nil { // No such imageb w.WriteHeader(http.StatusNotFound) return } i, _, err := image.Decode(bytes.NewBuffer(biglogo.Data)) if err != nil { // ERR_BADFORMAT w.WriteHeader(http.StatusNotFound) return } const max = 70 if sf == 0 { // We aim for less than max pixels in any dimension. if b := i.Bounds(); b.Dx() > max || b.Dy() > max { // If it's gigantic, it's more efficient to downsample first // and then resize; resizing will smooth out the roughness. if b.Dx() > 2*max || b.Dy() > 2*max { w, h := max*2, max*2 if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resample(i, i.Bounds(), w, h) b = i.Bounds() } w, h := max, max if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resize(i, i.Bounds(), w, h) } else { w, h := max, max if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resize(i, i.Bounds(), w, h) } } else { // We aim for a resize by ratio. b := i.Bounds() h := b.Dy() w := b.Dx() if sf > 0 && sf <= 2 { h = h * sf w = w * sf } else if sf < 0 && sf > -1 { sf = (sf * 2) + sf h = h * (1 / sf) w = w * (1 / sf) } i = resize.Resize(i, i.Bounds(), w, h) } // Encode as a new JPEG image. var buf bytes.Buffer err = jpeg.Encode(&buf, i, nil) if err != nil { // ERR_FAIL_ENCODE w.WriteHeader(http.StatusNotFound) return } // Save the image under a unique key, a hash of the image. simg.IdImg = model.RandId(20) simg.Data = buf.Bytes() simg.Name = biglogo.Name simg.Desc = biglogo.Desc simg.Sizepx = max simg.Sizepy = 0 simg.Url = biglogo.Url simg.Type = "jpeg" simg.Sp1 = biglogo.Sp1 simg.Sp2 = biglogo.Sp2 simg.Sp3 = biglogo.Sp3 simg.Sp4 = biglogo.Sp4 simg.Np1 = biglogo.Np1 simg.Np2 = biglogo.Np2 simg.Np3 = biglogo.Np3 simg.Np4 = biglogo.Np4 _, err = model.PutLogo(c, &simg) if err != nil { // ERR_DATASTORE // Don't return, stream image either way } w.Header().Set("Content-type", "image/jpeg") w.Write(simg.Data) /* m, _, err := image.Decode(bytes.NewBuffer(simg.Data)) model.Check(err) w.Header().Set("Content-type", "image/jpeg") jpeg.Encode(w, m, nil) */ } }
func slogores(c appengine.Context, id string, max int, sf int) int { var simg model.Image // Process biglogo if shortlogo doesn't exists // Save and Stream new shortlogo biglogo := model.GetLogo(c, id) if biglogo == nil { // No such imageb return -1 } i, _, err := image.Decode(bytes.NewBuffer(biglogo.Data)) if err != nil { // ERR_BADFORMAT return -1 } if sf == 0 { // We aim for less than 80 pixels in any dimension. if b := i.Bounds(); b.Dx() > max || b.Dy() > max { // If it's gigantic, it's more efficient to downsample first // and then resize; resizing will smooth out the roughness. if b.Dx() > 2*max || b.Dy() > 2*max { w, h := max*2, max*2 if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resample(i, i.Bounds(), w, h) b = i.Bounds() } w, h := max, max if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resize(i, i.Bounds(), w, h) } else { w, h := max, max if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resize(i, i.Bounds(), w, h) } } else { // We aim for a resize by ratio. b := i.Bounds() h := b.Dy() w := b.Dx() if sf > 0 && sf <= 2 { h = h * sf w = w * sf } else if sf < 0 && sf > -1 { sf = (sf * 2) + sf h = h * (1 / sf) w = w * (1 / sf) } i = resize.Resize(i, i.Bounds(), w, h) } // Encode as a new JPEG image. var buf bytes.Buffer err = jpeg.Encode(&buf, i, nil) if err != nil { // ERR_FAIL_ENCODE return -1 } // Save the image under a unique key, a hash of the image. shortlogo, _ := model.GetShortLogo(c, id) simg.Kind = "ShortLogo" if shortlogo != nil { simg.IdImg = shortlogo.IdImg } else { simg.IdImg = model.RandId(20) } simg.IdEmp = id simg.Data = buf.Bytes() simg.Name = biglogo.Name simg.Desc = biglogo.Desc simg.Sizepx = max simg.Sizepy = 0 simg.Url = biglogo.Url simg.Type = "jpeg" simg.Sp1 = biglogo.Sp1 simg.Sp2 = biglogo.Sp2 simg.Sp3 = biglogo.Sp3 simg.Sp4 = biglogo.Sp4 simg.Np1 = biglogo.Np1 simg.Np2 = biglogo.Np2 simg.Np3 = biglogo.Np3 simg.Np4 = biglogo.Np4 _, err = model.PutLogo(c, &simg) if err != nil { return -1 } return 0 }
// handler for '/'; if the request is a POST try to convert the image func upload(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) if r.Method != "POST" { // No upload; show the upload form. if err := uploadTemplate.Execute(w, ""); err != nil { c.Errorf("Can't execute uploadTempl: ", err) } return } // Grab the image data var buf bytes.Buffer f, _, err := r.FormFile("image") if err != nil { u := r.FormValue("url") // c.Infof("about to fetch %v\n", u) if len(u) == 0 { if err = uploadTemplate.Execute(w, ""); err != nil { c.Errorf("Can't execute uploadTempalte:", err) } return } client := urlfetch.Client(c) resp, err := client.Get(u) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer resp.Body.Close() buf.Reset() io.Copy(&buf, resp.Body) } else { defer f.Close() io.Copy(&buf, f) } // c.Infof("length of buffer is: %d\n", buf.Len()) i, _, err := image.Decode(&buf) check(err) const max = 300 if b := i.Bounds(); b.Dx() > max || b.Dy() > max { // If it's gigantic, it's more efficient to downsample first // and then resize; resizing will smooth out the roughness. if b.Dx() > 2*max || b.Dy() > 2*max { w, h := max, max if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resample(i, i.Bounds(), w, h) b = i.Bounds() } w, h := max/2, max/2 if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resize(i, i.Bounds(), w, h) } // Encode as a new ascii image buf.Reset() err = Encode(&buf, i) check(err) OutBuf := string(buf.Bytes()) // c.Infof("Done converting; buf:\n%v\n", OutBuf) w.Header().Set("Content-type", "text/html") uploadTemplate.Execute(w, OutBuf) }