Skip to content

Commit ee50154

Browse files
authored
Enable force ascii, implement image conversion to palletted image for Sixel support, which is now there (#4)
1 parent 158e972 commit ee50154

File tree

2 files changed

+55
-18
lines changed

2 files changed

+55
-18
lines changed

cmd/icat/icat.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
11
package main
22

33
import (
4+
"flag"
5+
"fmt"
46
"net/url"
57
"os"
68

79
"github.com/hilli/icat"
810
)
911

1012
func main() {
13+
// Define the -ascii flag
14+
forceASCII := flag.Bool("ascii", false, "Force ASCII art output")
1115

12-
args := os.Args[1:]
16+
// Define a custom usage function
17+
flag.Usage = func() {
18+
fmt.Fprintf(os.Stderr, "Usage: %s [options] <image-url-or-path>\n", os.Args[0])
19+
fmt.Fprintf(os.Stderr, "Options:\n")
20+
flag.PrintDefaults()
21+
}
22+
23+
flag.Parse()
24+
25+
// Get the remaining arguments after flag parsing
26+
args := flag.Args()
1327

1428
if len(args) == 0 {
29+
flag.Usage()
1530
os.Exit(0)
1631
}
1732

@@ -20,9 +35,9 @@ func main() {
2035

2136
url, err := url.Parse(arg)
2237
if err == nil && (url.Scheme == "http" || url.Scheme == "https") {
23-
err = icat.PrintImageURL(arg)
38+
err = icat.PrintImageURL(arg, *forceASCII)
2439
} else {
25-
err = icat.PrintImageFile(arg)
40+
err = icat.PrintImageFile(arg, *forceASCII)
2641
}
2742
if err != nil {
2843
os.Stderr.WriteString(err.Error())

print_image.go

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"bytes"
55
"fmt"
66
"image"
7+
"image/color/palette"
8+
"image/draw"
79
"io"
810
"net/http"
911
"os"
@@ -15,6 +17,10 @@ import (
1517

1618
ascii "github.com/qeesung/image2ascii/convert"
1719

20+
_ "image/gif"
21+
_ "image/jpeg"
22+
_ "image/png"
23+
1824
_ "golang.org/x/image/bmp"
1925
_ "golang.org/x/image/riff"
2026
_ "golang.org/x/image/tiff"
@@ -23,7 +29,7 @@ import (
2329
_ "golang.org/x/image/webp"
2430
)
2531

26-
func PrintImageFile(imageFileName string) error {
32+
func PrintImageFile(imageFileName string, forceASCII bool) error {
2733
imageFile, imageSize, err := util.FileAndStat(imageFileName)
2834
if err != nil {
2935
return err
@@ -39,10 +45,10 @@ func PrintImageFile(imageFileName string) error {
3945
if err != nil {
4046
return err
4147
}
42-
return PrintImage(img, imageFileName, imageSize)
48+
return PrintImage(img, imageFileName, imageSize, forceASCII)
4349
}
4450

45-
func PrintImageURL(imageURL string) error {
51+
func PrintImageURL(imageURL string, forceASCII bool) error {
4652
client := http.Client{
4753
Timeout: 5 * time.Second,
4854
}
@@ -62,11 +68,17 @@ func PrintImageURL(imageURL string) error {
6268
if err != nil {
6369
return err
6470
}
65-
return PrintImage(img, imageURL, resp.ContentLength)
71+
return PrintImage(img, imageURL, resp.ContentLength, forceASCII)
6672
}
6773

68-
func PrintImage(img *image.Image, filename string, imageSize int64) error {
74+
func PrintImage(img *image.Image, filename string, imageSize int64, forceASCII bool) error {
6975
var img2 image.Image = *img
76+
77+
if forceASCII {
78+
fmt.Print("\n", ConvertToASCII(img2))
79+
return nil
80+
}
81+
7082
sixelCapable, _ := rasterm.IsSixelCapable()
7183

7284
_, _, pw, ph := TermSize() // Get terminal height and width in pixels
@@ -94,19 +106,13 @@ func PrintImage(img *image.Image, filename string, imageSize int64) error {
94106
return rasterm.ItermWriteImage(os.Stdout, img2)
95107

96108
case sixelCapable:
97-
// TODO: Convert image to a paletted format
98-
// if iPaletted, bOK := img.(*image.Paletted); bOK {
99-
// return rasterm.SixelWriteImage(os.Stdout, iPaletted)
100-
// } else {
101-
// fmt.Println("[NOT PALETTED, SKIPPING.]")
102-
// return nil
103-
// }
109+
// Convert image to a paletted format
110+
palettedImg := ConvertToPaletted(img2)
111+
return rasterm.SixelWriteImage(os.Stdout, palettedImg)
104112

105113
default:
106114
// Ascii art fallback
107-
converter := ascii.NewImageConverter()
108-
convertOptions := ascii.DefaultOptions
109-
fmt.Print("\n", converter.Image2ASCIIString(img2, &convertOptions)) // Align image at the initial position instead of \n first?
115+
fmt.Print("\n", ConvertToASCII(img2)) // Align image at the initial position instead of \n first?
110116
}
111117
return nil
112118
}
@@ -119,3 +125,19 @@ func DecodeImage(imageData []byte) (*image.Image, error) {
119125
}
120126
return &image, nil
121127
}
128+
129+
// ConvertToPaletted converts an image.Image to an image.Paletted
130+
// Needed for Sixel conversion
131+
func ConvertToPaletted(img image.Image) *image.Paletted {
132+
bounds := img.Bounds()
133+
palettedImg := image.NewPaletted(bounds, palette.Plan9)
134+
draw.Draw(palettedImg, bounds, img, bounds.Min, draw.Over)
135+
return palettedImg
136+
}
137+
138+
// ASCII art conversion
139+
func ConvertToASCII(img image.Image) string {
140+
converter := ascii.NewImageConverter()
141+
convertOptions := ascii.DefaultOptions
142+
return converter.Image2ASCIIString(img, &convertOptions)
143+
}

0 commit comments

Comments
 (0)