func GetImageFromDatastore(w http.ResponseWriter, r *http.Request, key string) *image.RGBA { c := appengine.NewContext(r) dsObj, err := dsu.BufGet(w, r, "dsu.WrapBlob__"+key) util_err.Err_http(w, r, err, false) s := string(dsObj.VByte) img, whichFormat := conv.Base64_str_to_img(s) c.Infof("retrieved img from base64: format %v - subtype %T\n", whichFormat, img) i, ok := img.(*image.RGBA) util_err.Err_http(w, r, ok, false, "saved image needs to be reconstructible into a format png of subtype *image.RGBA") return i }
// An example demonstrating decoding JPEG img + examining its pixels. func imageAnalyze(w http.ResponseWriter, r *http.Request, m map[string]interface{}) { c := appengine.NewContext(r) // Decode the JPEG data. // If reading from file, create a reader with // reader, err := os.Open("testdata/video-001.q50.420.jpeg") // if err != nil { c.Errorf(err) } // defer reader.Close() img, whichFormat := conv.Base64_str_to_img(conv.Img_jpeg_base64) c.Infof("retrieved img from base64: format %v - type %T\n", whichFormat, img) bounds := img.Bounds() // Calculate a 16-bin histogram for m's red, green, blue and alpha components. // An image's bounds do not necessarily start at (0, 0), so the two loops start // at bounds.Min.Y and bounds.Min.X. Looping over Y first and X second is more // likely to result in better memory access patterns than X first and Y second. var histogram [16][4]int for y := bounds.Min.Y; y < bounds.Max.Y; y++ { for x := bounds.Min.X; x < bounds.Max.X; x++ { r, g, b, a := img.At(x, y).RGBA() // A color's RGBA method returns values in the range [0, 65535]. // Shifting by 12 reduces this to the range [0, 15]. histogram[r>>12][0]++ histogram[g>>12][1]++ histogram[b>>12][2]++ histogram[a>>12][3]++ } } b1 := new(bytes.Buffer) s1 := fmt.Sprintf("%-14s %6s %6s %6s %6s\n", "bin", "red", "green", "blue", "alpha") b1.WriteString(s1) for i, x := range histogram { s1 := fmt.Sprintf("0x%04x-0x%04x: %6d %6d %6d %6d\n", i<<12, (i+1)<<12-1, x[0], x[1], x[2], x[3]) b1.WriteString(s1) } w.Header().Set("Content-Type", "text/plain") w.Write(b1.Bytes()) }