Example #1
0
func makeImage(req *http.Request, caption, font string, pt, size, border, scale int, f func(x, y int) uint32) *image.RGBA {
	d := (size + 2*border) * scale
	csize := 0
	if caption != "" {
		if pt == 0 {
			pt = 11
		}
		csize = pt * 2
	}
	c := image.NewRGBA(image.Rect(0, 0, d, d+csize))

	// white
	u := &image.Uniform{C: color.White}
	draw.Draw(c, c.Bounds(), u, image.ZP, draw.Src)

	for y := 0; y < size; y++ {
		for x := 0; x < size; x++ {
			r := image.Rect((x+border)*scale, (y+border)*scale, (x+border+1)*scale, (y+border+1)*scale)
			rgba := f(x, y)
			u.C = color.RGBA{byte(rgba >> 24), byte(rgba >> 16), byte(rgba >> 8), byte(rgba)}
			draw.Draw(c, r, u, image.ZP, draw.Src)
		}
	}

	if csize != 0 {
		if font == "" {
			font = "data/luxisr.ttf"
		}
		ctxt := fs.NewContext(req)
		dat, _, err := ctxt.Read(font)
		if err != nil {
			panic(err)
		}
		tfont, err := freetype.ParseFont(dat)
		if err != nil {
			panic(err)
		}
		ft := freetype.NewContext()
		ft.SetDst(c)
		ft.SetDPI(100)
		ft.SetFont(tfont)
		ft.SetFontSize(float64(pt))
		ft.SetSrc(image.NewUniform(color.Black))
		ft.SetClip(image.Rect(0, 0, 0, 0))
		wid, err := ft.DrawString(caption, freetype.Pt(0, 0))
		if err != nil {
			panic(err)
		}
		p := freetype.Pt(d, d+3*pt/2)
		p.X -= wid.X
		p.X /= 2
		ft.SetClip(c.Bounds())
		ft.DrawString(caption, p)
	}

	return c
}
Example #2
0
// Show is the handler for showing a stored QR code.
func Show(w http.ResponseWriter, req *http.Request) {
	ctxt := fs.NewContext(req)
	tag := req.URL.Path[len("/qr/show/"):]
	png := strings.HasSuffix(tag, ".png")
	if png {
		tag = tag[:len(tag)-len(".png")]
	}
	if !isTagName(tag) {
		fmt.Fprintf(w, "Sorry, QR code not found\n")
		return
	}
	if req.FormValue("flag") == "1" {
		flag(w, req, tag, ctxt)
		return
	}
	data, _, err := ctxt.Read("qrsave/" + tag)
	if err != nil {
		fmt.Fprintf(w, "Sorry, QR code not found.\n")
		return
	}

	var m Image
	if err := json.Unmarshal(data, &m); err != nil {
		panic(err)
	}
	m.Tag = tag

	switch req.FormValue("size") {
	case "big":
		m.Scale *= 2
	case "small":
		m.Scale /= 2
	}

	if png {
		if err := m.Encode(req); err != nil {
			panic(err)
			return
		}
		w.Header().Set("Cache-Control", "public, max-age=3600")
		w.Write(m.Code.PNG())
		return
	}

	w.Header().Set("Cache-Control", "public, max-age=300")
	runTemplate(ctxt, w, "qr/permalink.html", &m)
}
Example #3
0
func upload(w http.ResponseWriter, req *http.Request, link string) {
	// Upload of a new image.
	// Copied from Moustachio demo.
	f, _, err := req.FormFile("image")
	if err != nil {
		fmt.Fprintf(w, "You need to select an image to upload.\n")
		return
	}
	defer f.Close()

	i, _, err := image.Decode(f)
	if err != nil {
		panic(err)
	}

	// Convert image to 128x128 gray+alpha.
	b := i.Bounds()
	const max = 128
	// If it's gigantic, it's more efficient to downsample first
	// and then resize; resizing will smooth out the roughness.
	var i1 *image.RGBA
	if b.Dx() > 4*max || b.Dy() > 4*max {
		w, h := 2*max, 2*max
		if b.Dx() > b.Dy() {
			h = b.Dy() * h / b.Dx()
		} else {
			w = b.Dx() * w / b.Dy()
		}
		i1 = resize.Resample(i, b, w, h)
	} else {
		// "Resample" to same size, just to convert to RGBA.
		i1 = resize.Resample(i, b, b.Dx(), b.Dy())
	}
	b = i1.Bounds()

	// Encode to PNG.
	dx, dy := 128, 128
	if b.Dx() > b.Dy() {
		dy = b.Dy() * dx / b.Dx()
	} else {
		dx = b.Dx() * dy / b.Dy()
	}
	i128 := resize.ResizeRGBA(i1, i1.Bounds(), dx, dy)

	var buf bytes.Buffer
	if err := png.Encode(&buf, i128); err != nil {
		panic(err)
	}

	h := md5.New()
	h.Write(buf.Bytes())
	tag := fmt.Sprintf("%x", h.Sum(nil))[:32]

	ctxt := fs.NewContext(req)
	if err := ctxt.Write("qr/upload/"+tag+".png", buf.Bytes()); err != nil {
		panic(err)
	}

	// Redirect with new image tag.
	// Redirect to draw with new image tag.
	http.Redirect(w, req, req.URL.Path+"?"+url.Values{"i": {tag}, "url": {link}}.Encode(), 302)
}