on main help sign in
refactor: use different ansi image library (#1964)
commit49a41de935eb6ae77eff4a9f3295055eec51c162 authorKujtim Hoxha <kujtimii.h@gmail.com> dateFri 23 Jan 2026, 15:58 (9 months ago) parent505283a
3 files changed+41−6
go.mod+2−1 go.sum+4−2 internal/ui/image/image.go+35−3
go.mod+2−1
@@ -31,7 +31,6 @@ require (
3131 github.com/charmbracelet/x/exp/ordered v0.1.0
3232 github.com/charmbracelet/x/exp/slice v0.0.0-20251201173703-9f73bfd934ff
3333 github.com/charmbracelet/x/exp/strings v0.0.0-20260119114936-fd556377ea59
34− github.com/charmbracelet/x/mosaic v0.0.0-20251215102626-e0db08df7383
3534 github.com/charmbracelet/x/powernap v0.0.0-20260113142046-c1fa3de7983b
3635 github.com/charmbracelet/x/term v0.2.2
3736 github.com/denisbrodbeck/machineid v1.0.1
@@ -41,6 +40,7 @@ require (
4140 github.com/google/uuid v1.6.0
4241 github.com/invopop/jsonschema v0.13.0
4342 github.com/joho/godotenv v1.5.1
43+ github.com/jordanella/go-ansi-paintbrush v0.0.0-20240728195301-b7ad996ecf3d
4444 github.com/lucasb-eyer/go-colorful v1.3.0
4545 github.com/mattn/go-isatty v0.0.20
4646 github.com/modelcontextprotocol/go-sdk v1.2.0
@@ -122,6 +122,7 @@ require (
122122 github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
123123 github.com/goccy/go-json v0.10.5 // indirect
124124 github.com/goccy/go-yaml v1.19.0 // indirect
125+ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
125126 github.com/google/go-cmp v0.7.0 // indirect
126127 github.com/google/jsonschema-go v0.3.0 // indirect
127128 github.com/google/s2a-go v0.1.9 // indirect
go.sum+4−2
@@ -122,8 +122,6 @@ github.com/charmbracelet/x/exp/strings v0.0.0-20260119114936-fd556377ea59 h1:cvP
122122github.com/charmbracelet/x/exp/strings v0.0.0-20260119114936-fd556377ea59/go.mod h1:/ehtMPNh9K4odGFkqYJKpIYyePhdp1hLBRvyY4bWkH8=
123123github.com/charmbracelet/x/json v0.2.0 h1:DqB+ZGx2h+Z+1s98HOuOyli+i97wsFQIxP2ZQANTPrQ=
124124github.com/charmbracelet/x/json v0.2.0/go.mod h1:opFIflx2YgXgi49xVUu8gEQ21teFAxyMwvOiZhIvWNM=
125−github.com/charmbracelet/x/mosaic v0.0.0-20251215102626-e0db08df7383 h1:YpTd2/abobMn/dCRM6Vo+G7JO/VS6RW0Ln3YkVJih8Y=
126−github.com/charmbracelet/x/mosaic v0.0.0-20251215102626-e0db08df7383/go.mod h1:r+fiJS0jb0Z5XKO+1mgKbwbPWzTy8e2dMjBMqa+XqsY=
127125github.com/charmbracelet/x/powernap v0.0.0-20260113142046-c1fa3de7983b h1:5ye9hzBKH623bMVz5auIuY6K21loCdxpRmFle2O9R/8=
128126github.com/charmbracelet/x/powernap v0.0.0-20260113142046-c1fa3de7983b/go.mod h1:cmdl5zlP5mR8TF2Y68UKc7hdGUDiSJ2+4hk0h04Hsx4=
129127github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
@@ -189,6 +187,8 @@ github.com/goccy/go-yaml v1.19.0 h1:EmkZ9RIsX+Uq4DYFowegAuJo8+xdX3T/2dwNPXbxEYE=
189187github.com/goccy/go-yaml v1.19.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
190188github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
191189github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
190+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
191+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
192192github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
193193github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
194194github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
@@ -221,6 +221,8 @@ github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcI
221221github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
222222github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
223223github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
224+github.com/jordanella/go-ansi-paintbrush v0.0.0-20240728195301-b7ad996ecf3d h1:on25kP+Sx7sxUMRQiA8gdcToAGet4DK/EIA30mXre+4=
225+github.com/jordanella/go-ansi-paintbrush v0.0.0-20240728195301-b7ad996ecf3d/go.mod h1:SV0W0APWP9MZ1/gfDQ/NzzTlWdIgYZ/ZbpN4d/UXRYw=
224226github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
225227github.com/kaptinlin/go-i18n v0.2.2 h1:kebVCZme/BrCTqonh/J+VYCl1+Of5C18bvyn3DRPl5M=
226228github.com/kaptinlin/go-i18n v0.2.2/go.mod h1:MiwkeHryBopAhC/M3zEwIM/2IN8TvTqJQswPw6kceqM=
internal/ui/image/image.go+35−3
@@ -16,8 +16,8 @@ import (
1616 uv "github.com/charmbracelet/ultraviolet"
1717 "github.com/charmbracelet/x/ansi"
1818 "github.com/charmbracelet/x/ansi/kitty"
19− "github.com/charmbracelet/x/mosaic"
2019 "github.com/disintegration/imaging"
20+ paintbrush "github.com/jordanella/go-ansi-paintbrush"
2121)
2222
2323// Capabilities represents the capabilities of displaying images on the
@@ -246,8 +246,40 @@ func (e Encoding) Render(id string, cols, rows int) string {
246246
247247 switch e {
248248 case EncodingBlocks:
249− m := mosaic.New().Width(cols).Height(rows).Scale(1)
250− return strings.TrimSpace(m.Render(img))
249+ canvas := paintbrush.New()
250+ canvas.SetImage(img)
251+ canvas.SetWidth(cols)
252+ canvas.SetHeight(rows)
253+ canvas.Weights = map[rune]float64{
254+ '': .95,
255+ '': .95,
256+ '▁': .9,
257+ '▂': .9,
258+ '▃': .9,
259+ '▄': .9,
260+ '▅': .9,
261+ '▆': .85,
262+ '█': .85,
263+ '▊': .95,
264+ '▋': .95,
265+ '▌': .95,
266+ '▍': .95,
267+ '▎': .95,
268+ '▏': .95,
269+ '●': .95,
270+ '◀': .95,
271+ '▲': .95,
272+ '▶': .95,
273+ '▼': .9,
274+ '○': .8,
275+ '◉': .95,
276+ '◧': .9,
277+ '◨': .9,
278+ '◩': .9,
279+ '◪': .9,
280+ }
281+ canvas.Paint()
282+ return strings.TrimSpace(canvas.GetResult())
251283 case EncodingKitty:
252284 // Build Kitty graphics unicode place holders
253285 var fg color.Color