11package main
22
33import (
4- "bufio"
54 "flag"
65 "fmt"
76 "image"
7+ "image/color"
88 _ "image/gif"
99 _ "image/jpeg"
1010 _ "image/png"
1111 "math"
1212 "os"
13+ "runtime"
14+ "strings"
15+ "time"
1316
1417 "github.com/BurntSushi/graphics-go/graphics"
1518 "github.com/mattn/go-sixel"
19+ "golang.org/x/term"
1620)
1721
1822var (
@@ -37,6 +41,27 @@ func render(filename string) error {
3741 if err != nil {
3842 return err
3943 }
44+
45+ bounds := img .Bounds ()
46+ height := ((bounds .Dy ()+ 5 )/ 6 )* 6 + 7
47+ tmp := image .NewNRGBA64 (image .Rect (0 , 0 , bounds .Dx (), height ))
48+ for y := 0 ; y < bounds .Dy (); y ++ {
49+ for x := 0 ; x < bounds .Dx (); x ++ {
50+ r , g , b , a := img .At (bounds .Min .X + x , bounds .Min .Y + y ).RGBA ()
51+ if a == 0 {
52+ tmp .Set (x , y , bg )
53+ } else {
54+ tmp .Set (x , y , color.NRGBA64 {uint16 (r ), uint16 (g ), uint16 (b ), 0xFFFF })
55+ }
56+ }
57+ }
58+ for y := bounds .Dy (); y < height ; y ++ {
59+ for x := 0 ; x < bounds .Dx (); x ++ {
60+ tmp .Set (x , y , bg )
61+ }
62+ }
63+ img = tmp
64+
4065 if * fResize != "" {
4166 var w , h uint
4267 fmt .Sscanf (* fResize , "%dx%d" , & w , & h )
@@ -63,7 +88,7 @@ func render(filename string) error {
6388 cos = sin
6489 }
6590 tmp := image .NewNRGBA64 (image .Rect (0 , 0 , int (cos * d ), int (sin * d )))
66- err = graphics .Rotate (tmp , img , & graphics.RotateOptions {* fRotate })
91+ err = graphics .Rotate (tmp , img , & graphics.RotateOptions {Angle : * fRotate })
6792 if err != nil {
6893 return err
6994 }
@@ -74,20 +99,65 @@ func render(filename string) error {
7499 var s int
75100 fmt .Sscanf (* fBlur , "%f,%d" , & d , & s )
76101 tmp := image .NewNRGBA64 (img .Bounds ())
77- err = graphics .Blur (tmp , img , & graphics.BlurOptions {d , s })
102+ err = graphics .Blur (tmp , img , & graphics.BlurOptions {StdDev : d , Size : s })
78103 if err != nil {
79104 return err
80105 }
81106 img = tmp
82107 }
83- buf := bufio .NewWriter (os .Stdout )
84- defer buf .Flush ()
85-
86- enc := sixel .NewEncoder (buf )
108+ enc := sixel .NewEncoder (os .Stdout )
87109 enc .Dither = true
88110 return enc .Encode (img )
89111}
90112
113+ var bg = color.RGBA64 {0 , 0 , 0 , 0xFFFF }
114+
115+ func init () {
116+ if runtime .GOOS == "windows" {
117+ return
118+ }
119+ tty , err := os .OpenFile ("/dev/tty" , os .O_RDWR , 0 )
120+ if err != nil {
121+ return
122+ }
123+ defer tty .Close ()
124+
125+ fd := int (tty .Fd ())
126+ oldState , err := term .MakeRaw (fd )
127+ if err != nil {
128+ return
129+ }
130+ defer term .Restore (fd , oldState )
131+
132+ tty .Write ([]byte ("\x1b ]11;?\x1b \\ " ))
133+ time .Sleep (100 * time .Millisecond )
134+
135+ var bb []byte
136+
137+ for {
138+ var b [1 ]byte
139+ _ , err = tty .Read (b [:])
140+ if err != nil || b [0 ] == '\\' || b [0 ] == 0x0a {
141+ break
142+ }
143+ bb = append (bb , b [0 ])
144+ }
145+ if pos := strings .Index (string (bb ), "rgb:" ); pos != - 1 {
146+ bb = bb [pos + 4 :]
147+ pos = strings .Index (string (bb ), "\x1b " )
148+ if pos != - 1 {
149+ bb = bb [:pos ]
150+ }
151+ var r , g , b uint16
152+ n , err := fmt .Sscanf (string (bb ), "%x/%x/%x" , & r , & g , & b )
153+ if err != nil || n != 3 {
154+ bg = color.RGBA64 {0 , 0 , 0 , 0xFFFF }
155+ } else {
156+ bg = color.RGBA64 {r , g , b , 0xFFFF }
157+ }
158+ }
159+ }
160+
91161func main () {
92162 flag .Usage = func () {
93163 fmt .Println ("Usage of " + os .Args [0 ] + ": gosr [images]" )
@@ -98,6 +168,7 @@ func main() {
98168 flag .Usage ()
99169 os .Exit (1 )
100170 }
171+
101172 for _ , arg := range flag .Args () {
102173 err := render (arg )
103174 if err != nil {
0 commit comments