Commit 04a6e8da authored by santiaago's avatar santiaago
Browse files

add svg support for checkerboard routes and add extract pkg to hanlde param extraction from urls.

parent ff7e0b85
Loading
Loading
Loading
Loading
+23 −24
Original line number Diff line number Diff line
package checkerboard

import (
	"github.com/ajstarks/svgo"
	"github.com/taironas/tinygraphs/colors"
	"github.com/taironas/tinygraphs/draw"
	"github.com/taironas/tinygraphs/extract"
	"github.com/taironas/tinygraphs/misc"
	"github.com/taironas/tinygraphs/write"
	"image"
	"image/color"
	"log"
	"net/http"
	"strconv"
)

// Color is the handler for /checkerboard/[0-8]
@@ -19,37 +20,35 @@ func Color(w http.ResponseWriter, r *http.Request) {
	if err != nil {
		log.Printf("error when extracting permalink id: %v", err)
	} else {
		size := size(r)
		m := image.NewRGBA(image.Rect(0, 0, size, size))
		size := extract.Size(r)
		colorMap := colors.MapOfColorPatterns()
		if format := extract.Format(r); format == extract.JPEG {
			m := image.NewRGBA(image.Rect(0, 0, size, size))
			draw.Grid6X6(m, colorMap[int(intID)][0], colorMap[int(intID)][1])
			var img image.Image = m
			write.ImageJPEG(w, &img)
		} else if format == extract.SVG {
			canvas := svg.New(w)
			draw.Grid6X6SVG(canvas, colorMap[int(intID)][0], colorMap[int(intID)][1], size)
			write.ImageSVG(w, canvas)
		}
	}
}

// Checkerboard is the handler for /checkerboard/
// build a 6x6 checkerboard with alternate black and white colors.
func Checkerboard(w http.ResponseWriter, r *http.Request) {
	size := size(r)
	m := image.NewRGBA(image.Rect(0, 0, size, size))
	size := extract.Size(r)
	color1 := color.RGBA{uint8(255), uint8(255), 255, 255}
	color2 := color.RGBA{uint8(0), uint8(0), 0, 255}
	if format := extract.Format(r); format == extract.JPEG {
		m := image.NewRGBA(image.Rect(0, 0, size, size))
		draw.Grid6X6(m, color1, color2)
		var img image.Image = m
		write.ImageJPEG(w, &img)
	} else if format == extract.SVG {
		canvas := svg.New(w)
		draw.Grid6X6SVG(canvas, color1, color2, size)
		write.ImageSVG(w, canvas)
	}

// extract size from HTTP request and return it.
func size(r *http.Request) int {
	strSize := r.FormValue("size")
	if len(strSize) > 0 {
		if size, errSize := strconv.ParseInt(strSize, 0, 64); errSize == nil {
			isize := int(size)
			if isize > 0 && isize < 1000 {
				return int(size)
			}
		}
	}
	return 210
}
+9 −8
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ import (
	"github.com/ajstarks/svgo"
	"github.com/taironas/tinygraphs/colors"
	"github.com/taironas/tinygraphs/draw"
	"github.com/taironas/tinygraphs/extract"
	"github.com/taironas/tinygraphs/misc"
	"github.com/taironas/tinygraphs/write"
	"image"
@@ -14,22 +15,22 @@ import (
// handler for "/squares/random"
// generates a black and white grid random image.
func Random(w http.ResponseWriter, r *http.Request) {
	size := size(r)
	size := extract.Size(r)
	colorMap := colors.MapOfColorPatterns()
	bg, err1 := background(r)
	bg, err1 := extract.Background(r)
	if err1 != nil {
		bg = colorMap[0][0]
	}
	fg, err2 := foreground(r)
	fg, err2 := extract.Foreground(r)
	if err2 != nil {
		fg = colorMap[0][1]
	}
	if format := format(r); format == JPEG {
	if format := extract.Format(r); format == extract.JPEG {
		m := image.NewRGBA(image.Rect(0, 0, size, size))
		draw.RandomGrid6X6(m, bg, fg)
		var img image.Image = m
		write.ImageJPEG(w, &img)
	} else if format == SVG {
	} else if format == extract.SVG {
		canvas := svg.New(w)
		draw.RandomGrid6X6SVG(canvas, bg, fg, size)
		write.ImageSVG(w, canvas)
@@ -43,14 +44,14 @@ func RandomColor(w http.ResponseWriter, r *http.Request) {
	if err != nil {
		log.Printf("error when extracting permalink id: %v", err)
	} else {
		size := size(r)
		size := extract.Size(r)
		colorMap := colors.MapOfColorPatterns()
		if format := format(r); format == JPEG {
		if format := extract.Format(r); format == extract.JPEG {
			m := image.NewRGBA(image.Rect(0, 0, size, size))
			draw.RandomGrid6X6(m, colorMap[int(intID)][0], colorMap[int(intID)][1])
			var img image.Image = m
			write.ImageJPEG(w, &img)
		} else if format == SVG {
		} else if format == extract.SVG {
			canvas := svg.New(w)
			draw.RandomGrid6X6SVG(canvas, colorMap[int(intID)][0], colorMap[int(intID)][1], size)
			write.ImageSVG(w, canvas)
+9 −26
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ import (
	"github.com/ajstarks/svgo"
	tgColors "github.com/taironas/tinygraphs/colors"
	"github.com/taironas/tinygraphs/draw"
	"github.com/taironas/tinygraphs/extract"
	"github.com/taironas/tinygraphs/misc"
	"github.com/taironas/tinygraphs/write"
	"image"
@@ -40,21 +41,21 @@ func Square(w http.ResponseWriter, r *http.Request) {
		}

		colorMap := tgColors.MapOfColorPatterns()
		bg, err1 := background(r)
		bg, err1 := extract.Background(r)
		if err1 != nil {
			bg = colorMap[0][0]
		}
		fg, err2 := foreground(r)
		fg, err2 := extract.Foreground(r)
		if err2 != nil {
			fg = colorMap[0][1]
		}
		size := size(r)
		if format := format(r); format == JPEG {
		size := extract.Size(r)
		if format := extract.Format(r); format == extract.JPEG {
			m := image.NewRGBA(image.Rect(0, 0, size, size))
			draw.Squares(m, key, bg, fg)
			var img image.Image = m
			write.ImageJPEG(w, &img)
		} else if format == SVG {
		} else if format == extract.SVG {
			canvas := svg.New(w)
			draw.SquaresSVG(canvas, key, bg, fg, size)
			write.ImageSVG(w, canvas)
@@ -87,14 +88,14 @@ func Color(w http.ResponseWriter, r *http.Request) {
				}
			}

			size := size(r)
			size := extract.Size(r)
			colorMap := tgColors.MapOfColorPatterns()
			if format := format(r); format == JPEG {
			if format := extract.Format(r); format == extract.JPEG {
				m := image.NewRGBA(image.Rect(0, 0, size, size))
				draw.Squares(m, key, colorMap[int(colorId)][0], colorMap[int(colorId)][1])
				var img image.Image = m
				write.ImageJPEG(w, &img)
			} else if format == SVG {
			} else if format == extract.SVG {
				canvas := svg.New(w)
				draw.SquaresSVG(canvas, key, colorMap[int(colorId)][0], colorMap[int(colorId)][1], size)
				write.ImageSVG(w, canvas)
@@ -104,21 +105,3 @@ func Color(w http.ResponseWriter, r *http.Request) {
		}
	}
}

// HexToRGB converts an Hex string to a RGB triple.
func hexToRGB(h string) (uint8, uint8, uint8, error) {
	if len(h) > 0 && h[0] == '#' {
		h = h[1:]
	}
	if len(h) == 3 {
		h = h[:1] + h[:1] + h[1:2] + h[1:2] + h[2:] + h[2:]
	}
	if len(h) == 6 {
		if rgb, err := strconv.ParseUint(string(h), 16, 32); err == nil {
			return uint8(rgb >> 16), uint8((rgb >> 8) & 0xFF), uint8(rgb & 0xFF), nil
		} else {
			return 0, 0, 0, err
		}
	}
	return 0, 0, 0, nil
}
+24 −0
Original line number Diff line number Diff line
@@ -30,6 +30,30 @@ func Grid6X6(m *image.RGBA, color1, color2 color.RGBA) {
	}
}

// Grid6X6SVG builds an image with 6X6 quadrants of alternate colors.
func Grid6X6SVG(canvas *svg.SVG, color1, color2 color.RGBA, size int) {
	canvas.Start(size, size)
	squares := 6
	quadrantSize := size / squares
	colorMap := make(map[int]color.RGBA)
	for yQ := 0; yQ < squares; yQ++ {
		y := yQ * quadrantSize
		colorMap = make(map[int]color.RGBA)

		for xQ := 0; xQ < squares; xQ++ {
			x := xQ * quadrantSize
			if _, ok := colorMap[xQ]; !ok {
				if (xQ+yQ)%2 == 0 {
					colorMap[xQ] = color1
				} else {
					colorMap[xQ] = color2
				}
			}
			canvas.Rect(x, y, quadrantSize, quadrantSize, fillFromRGBA(colorMap[xQ]))
		}
	}
}

// RandomGrid6X6 builds a grid image with with 2 colors selected at random for each quadrant.
func RandomGrid6X6(m *image.RGBA, color1, color2 color.RGBA) {
	size := m.Bounds().Size()
+26 −7
Original line number Diff line number Diff line
package squares
// Package extract provides a set of functions to extract parameters from an http:Request.
package extract

import (
	"fmt"
@@ -9,7 +10,7 @@ import (
)

// extract hexadecimal code background from HTTP request and return color.RGBA
func background(req *http.Request) (color.RGBA, error) {
func Background(req *http.Request) (color.RGBA, error) {
	bg := req.FormValue("bg")
	if len(bg) == 0 {
		return color.RGBA{}, fmt.Errorf("background: wrong input")
@@ -19,7 +20,7 @@ func background(req *http.Request) (color.RGBA, error) {
}

// extract hexadecimal code foreground from HTTP request and return color.RGBA
func foreground(req *http.Request) (color.RGBA, error) {
func Foreground(req *http.Request) (color.RGBA, error) {
	fg := req.FormValue("fg")
	if len(fg) == 0 {
		return color.RGBA{}, fmt.Errorf("background: wrong input")
@@ -29,7 +30,7 @@ func foreground(req *http.Request) (color.RGBA, error) {
}

// extract size from HTTP request and return it.
func size(r *http.Request) int {
func Size(r *http.Request) int {
	strSize := r.FormValue("size")
	if len(strSize) > 0 {
		if size, errSize := strconv.ParseInt(strSize, 0, 64); errSize == nil {
@@ -42,14 +43,14 @@ func size(r *http.Request) int {
	return 210
}

type Format int
type ImgFormat int

const (
	JPEG Format = iota
	JPEG ImgFormat = iota
	SVG
)

func format(r *http.Request) Format {
func Format(r *http.Request) ImgFormat {
	strFmt := strings.ToLower(r.FormValue("fmt"))
	if len(strFmt) > 0 {
		if strFmt == "svg" {
@@ -60,3 +61,21 @@ func format(r *http.Request) Format {
	}
	return JPEG
}

// HexToRGB converts an Hex string to a RGB triple.
func hexToRGB(h string) (uint8, uint8, uint8, error) {
	if len(h) > 0 && h[0] == '#' {
		h = h[1:]
	}
	if len(h) == 3 {
		h = h[:1] + h[:1] + h[1:2] + h[1:2] + h[2:] + h[2:]
	}
	if len(h) == 6 {
		if rgb, err := strconv.ParseUint(string(h), 16, 32); err == nil {
			return uint8(rgb >> 16), uint8((rgb >> 8) & 0xFF), uint8(rgb & 0xFF), nil
		} else {
			return 0, 0, 0, err
		}
	}
	return 0, 0, 0, nil
}