diff --git a/fastgif_lut.go b/fastgif_lut.go
deleted file mode 100644
index 9cd4b11..0000000
--- a/fastgif_lut.go
+++ /dev/null
@@ -1,260 +0,0 @@
-package main
-
-var FastGifLut = [256]int{
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
-}
diff --git a/wrp.go b/wrp.go
index 635f753..d9844b4 100644
--- a/wrp.go
+++ b/wrp.go
@@ -130,7 +130,7 @@ func (rq *wrpReq) parseForm() {
rq.keys = rq.r.FormValue("k")
rq.buttons = rq.r.FormValue("Fn")
rq.imgType = rq.r.FormValue("t")
- if rq.imgType != "fastgif" && rq.imgType != "gif" && rq.imgType != "png" {
+ if rq.imgType != "gif" && rq.imgType != "png" {
rq.imgType = defType
}
log.Printf("%s WrpReq from UI Form: %+v\n", rq.r.RemoteAddr, rq)
@@ -236,6 +236,45 @@ func chromedpCaptureScreenshot(res *[]byte, h int64) chromedp.Action {
})
}
+func gifPalette(i image.Image, n int64) image.Image {
+ switch n {
+ case 2:
+ i = halfgone.FloydSteinbergDitherer{}.Apply(halfgone.ImageToGray(i))
+ case 216:
+ var FastGifLut = [256]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}
+ r := i.Bounds()
+ // NOTE: the color index computation below works only for palette.WebSafe!
+ p := image.NewPaletted(r, palette.WebSafe)
+ if i64, ok := i.(image.RGBA64Image); ok {
+ for y := r.Min.Y; y < r.Max.Y; y++ {
+ for x := r.Min.X; x < r.Max.X; x++ {
+ c := i64.RGBA64At(x, y)
+ r6 := FastGifLut[c.R>>8]
+ g6 := FastGifLut[c.G>>8]
+ b6 := FastGifLut[c.B>>8]
+ p.SetColorIndex(x, y, uint8(36*r6+6*g6+b6))
+ }
+ }
+ } else {
+ for y := r.Min.Y; y < r.Max.Y; y++ {
+ for x := r.Min.X; x < r.Max.X; x++ {
+ c := i.At(x, y)
+ r, g, b, _ := c.RGBA()
+ r6 := FastGifLut[r&0xff]
+ g6 := FastGifLut[g&0xff]
+ b6 := FastGifLut[b&0xff]
+ p.SetColorIndex(x, y, uint8(36*r6+6*g6+b6))
+ }
+ }
+ }
+ i = p
+ default:
+ q := median.Quantizer(n)
+ i = q.Paletted(i)
+ }
+ return i
+}
+
// Capture currently rendered web page to an image and fake ISMAP
func (rq *wrpReq) capture() {
var err error
@@ -283,60 +322,22 @@ func (rq *wrpReq) capture() {
return
}
seq := rand.Intn(9999)
- var imgpath string
+ imgpath := fmt.Sprintf("/img/%04d.%s", seq, rq.imgType)
mappath := fmt.Sprintf("/map/%04d.map", seq)
ismap[mappath] = *rq
var ssize string
var iw, ih int
switch rq.imgType {
- case "fastgif":
- fallthrough
case "gif":
- imgpath = fmt.Sprintf("/img/%04d.gif", seq)
i, err := png.Decode(bytes.NewReader(pngcap))
if err != nil {
- log.Printf("%s Failed to decode screenshot: %s\n", rq.r.RemoteAddr, err)
- fmt.Fprintf(rq.w, "
Unable to decode page screenshot:
%s
\n", err)
+ log.Printf("%s Failed to decode PNG screenshot: %s\n", rq.r.RemoteAddr, err)
+ fmt.Fprintf(rq.w, "
Unable to decode page PNG screenshot:
%s
\n", err)
return
}
- if rq.colors == 2 {
- gray := halfgone.ImageToGray(i)
- i = halfgone.FloydSteinbergDitherer{}.Apply(gray)
- }
- var gifbuf bytes.Buffer
st := time.Now()
- var p *image.Paletted
- if rq.imgType == "fastgif" {
- r := i.Bounds()
- // NOTE: the color index computation below works only for palette.WebSafe!
- p = image.NewPaletted(r, palette.WebSafe)
- if i64, ok := i.(image.RGBA64Image); ok {
- for y := r.Min.Y; y < r.Max.Y; y++ {
- for x := r.Min.X; x < r.Max.X; x++ {
- c := i64.RGBA64At(x, y)
- r6 := FastGifLut[c.R>>8]
- g6 := FastGifLut[c.G>>8]
- b6 := FastGifLut[c.B>>8]
- p.SetColorIndex(x, y, uint8(36*r6+6*g6+b6))
- }
- }
- } else {
- for y := r.Min.Y; y < r.Max.Y; y++ {
- for x := r.Min.X; x < r.Max.X; x++ {
- c := i.At(x, y)
- r, g, b, _ := c.RGBA()
- r6 := FastGifLut[r&0xff]
- g6 := FastGifLut[g&0xff]
- b6 := FastGifLut[b&0xff]
- p.SetColorIndex(x, y, uint8(36*r6+6*g6+b6))
- }
- }
- }
- } else {
- q := median.Quantizer(rq.colors)
- p = q.Paletted(i)
- }
- err = gif.Encode(&gifbuf, p, &gif.Options{})
+ var gifbuf bytes.Buffer
+ err = gif.Encode(&gifbuf, gifPalette(i, rq.colors), &gif.Options{})
if err != nil {
log.Printf("%s Failed to encode GIF: %s\n", rq.r.RemoteAddr, err)
fmt.Fprintf(rq.w, "
Unable to encode GIF:
%s
\n", err)
@@ -346,16 +347,15 @@ func (rq *wrpReq) capture() {
ssize = fmt.Sprintf("%.0f KB", float32(len(gifbuf.Bytes()))/1024.0)
iw = i.Bounds().Max.X
ih = i.Bounds().Max.Y
- log.Printf("%s Encoded GIF image: %s, Size: %s, Colors: %d, %dx%d, Time: %vms\n", rq.r.RemoteAddr, imgpath, ssize, rq.colors, iw, ih, time.Since(st).Milliseconds())
+ log.Printf("%s Encoded GIF image: %s, Size: %s, Colors: %d, Res: %dx%d, Time: %vms\n", rq.r.RemoteAddr, imgpath, ssize, rq.colors, iw, ih, time.Since(st).Milliseconds())
case "png":
- imgpath = fmt.Sprintf("/img/%04d.png", seq)
pngbuf := bytes.NewBuffer(pngcap)
img[imgpath] = *pngbuf
cfg, _, _ := image.DecodeConfig(pngbuf)
ssize = fmt.Sprintf("%.0f KB", float32(len(pngbuf.Bytes()))/1024.0)
iw = cfg.Width
ih = cfg.Height
- log.Printf("%s Got PNG image: %s, Size: %s, %dx%d\n", rq.r.RemoteAddr, imgpath, ssize, iw, ih)
+ log.Printf("%s Got PNG image: %s, Size: %s, Res: %dx%d\n", rq.r.RemoteAddr, imgpath, ssize, iw, ih)
}
rq.printHTML(printParams{
bgColor: fmt.Sprintf("#%02X%02X%02X", r, g, b),
@@ -493,8 +493,8 @@ func main() {
flag.BoolVar(&headless, "h", true, "Headless mode - hide browser window")
flag.BoolVar(&debug, "d", false, "Debug ChromeDP")
flag.BoolVar(&noDel, "n", false, "Do not free maps and images after use")
- flag.StringVar(&defType, "t", "png", "Image type: fastgif|gif|png")
- flag.StringVar(&fgeom, "g", "1152x600x256", "Geometry: width x height x colors, height can be 0 for unlimited")
+ flag.StringVar(&defType, "t", "gif", "Image type: gif|png")
+ flag.StringVar(&fgeom, "g", "1152x600x216", "Geometry: width x height x colors, height can be 0 for unlimited")
flag.StringVar(&tHTML, "ui", "wrp.html", "HTML template file for the UI")
flag.Parse()
if len(os.Getenv("PORT")) > 0 {
diff --git a/wrp.html b/wrp.html
index cbd72e3..bbc494e 100644
--- a/wrp.html
+++ b/wrp.html
@@ -21,12 +21,12 @@
T
C