termimage

package
v1.16.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 2, 2024 License: BSD-3-Clause Imports: 9 Imported by: 0

Documentation

Overview

Package termimage providers a function that can be used to print low resolution images on the terminal. The exact method of presentation will depend on the image type and the terminal's capabilities.

An image's width in pixels must not exceed the width of the terminal, or the function will fail. If the writer is not connected to a terminal, or if the width of the terminal cannot be determined, then the width will default to 255 characters.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrWidthTooSmall = errors.New("terminal width is too small for image")
)

Functions

func DrawImage

func DrawImage(w io.Writer, f *sgr.Formatter, src image.Image) error
Example
package main

import (
	"bytes"
	"fmt"
	"image"
	"image/color"

	"git.sr.ht/~rj/sgr"
	"git.sr.ht/~rj/sgr/termimage"
)

func main() {
	src := makeRGBA()

	// Force the use of an ANSI terminal, with color codes.
	f := sgr.NewFormatterWithANSI()
	buf := &bytes.Buffer{}
	err := termimage.DrawImage(buf, f, src)
	if err != nil {
		panic(err) // Error checking elided for example.
	}

	for _, v := range bytes.Split(buf.Bytes(), []byte{'\n'}) {
		fmt.Printf("%q\n", v)
	}

}

func makeRGBA() *image.RGBA {
	bounds := image.Rect(0, 0, 8, 3)
	src := image.NewRGBA(bounds)

	for y := 0; y < 3; y++ {
		src.SetRGBA((0+y)%8, y, color.RGBA{A: 0xFF})
		src.SetRGBA((1+y)%8, y, color.RGBA{R: 0xff, A: 0xFF})
		src.SetRGBA((2+y)%8, y, color.RGBA{R: 0xff, G: 0xff, A: 0xFF})
		src.SetRGBA((3+y)%8, y, color.RGBA{G: 0xff, A: 0xFF})
		src.SetRGBA((4+y)%8, y, color.RGBA{G: 0xff, B: 0xff, A: 0xFF})
		src.SetRGBA((5+y)%8, y, color.RGBA{B: 0xff, A: 0xFF})
		src.SetRGBA((6+y)%8, y, color.RGBA{R: 0xff, B: 0xff, A: 0xFF})
		src.SetRGBA((7+y)%8, y, color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xFF})
	}

	return src
}
Output:

"\x1b[30;107m▀\x1b[0m\x1b[91;40m▀\x1b[0m\x1b[93;101m▀\x1b[0m\x1b[92;103m▀\x1b[0m\x1b[96;102m▀\x1b[0m\x1b[94;106m▀\x1b[0m\x1b[95;104m▀\x1b[0m\x1b[97;105m▀\x1b[0m"
"\x1b[95;40m▀\x1b[0m\x1b[97;40m▀\x1b[0m\x1b[30;40m▀\x1b[0m\x1b[91;40m▀\x1b[0m\x1b[93;40m▀\x1b[0m\x1b[92;40m▀\x1b[0m\x1b[96;40m▀\x1b[0m\x1b[94;40m▀\x1b[0m"
"\x1b[0m"
Example (Alpha)
package main

import (
	"image"
	"os"

	"git.sr.ht/~rj/sgr"
	"git.sr.ht/~rj/sgr/termimage"
)

func main() {
	bounds := image.Rect(0, 0, 16, 8)
	src := image.NewAlpha(bounds)

	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			src.Pix[src.PixOffset(x, y)] = uint8((y*y + x*x) * 255 / (256 + 64))
		}
	}

	f := sgr.NewFormatter()
	err := termimage.DrawImage(os.Stdout, f, src)
	if err != nil {
		panic(err) // Error checking elided for example.
	}

}
Output:

.........+++++++
.........+++++++
.........+++++++
.........+++++++
.........++++++#
........+++++++#
.......++++++++#
......++++++++##
Example (Gray)
package main

import (
	"image"
	"os"

	"git.sr.ht/~rj/sgr"
	"git.sr.ht/~rj/sgr/termimage"
)

func main() {
	bounds := image.Rect(0, 0, 16, 8)
	src := image.NewGray(bounds)

	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			src.Pix[src.PixOffset(x, y)] = uint8((y*y + x*x) * 255 / (256 + 64))
		}
	}

	f := sgr.NewFormatter()
	err := termimage.DrawImage(os.Stdout, f, src)
	if err != nil {
		panic(err) // Error checking elided for example.
	}

}
Output:

.........+++++++
.........+++++++
.........+++++++
.........+++++++
.........++++++#
........+++++++#
.......++++++++#
......++++++++##
Example (Mono)
package main

import (
	"image"
	"image/color"
	"os"

	"git.sr.ht/~rj/sgr/termimage"
)

func main() {
	src := makeRGBA()

	// Force the use of a monochrome terminal.  DrawImage will convert the image
	// to grayscale, and then print using ascii characters.
	err := termimage.DrawImage(os.Stdout, nil, src)
	if err != nil {
		panic(err) // Error checking elided for example.
	}

}

func makeRGBA() *image.RGBA {
	bounds := image.Rect(0, 0, 8, 3)
	src := image.NewRGBA(bounds)

	for y := 0; y < 3; y++ {
		src.SetRGBA((0+y)%8, y, color.RGBA{A: 0xFF})
		src.SetRGBA((1+y)%8, y, color.RGBA{R: 0xff, A: 0xFF})
		src.SetRGBA((2+y)%8, y, color.RGBA{R: 0xff, G: 0xff, A: 0xFF})
		src.SetRGBA((3+y)%8, y, color.RGBA{G: 0xff, A: 0xFF})
		src.SetRGBA((4+y)%8, y, color.RGBA{G: 0xff, B: 0xff, A: 0xFF})
		src.SetRGBA((5+y)%8, y, color.RGBA{B: 0xff, A: 0xFF})
		src.SetRGBA((6+y)%8, y, color.RGBA{R: 0xff, B: 0xff, A: 0xFF})
		src.SetRGBA((7+y)%8, y, color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xFF})
	}

	return src
}
Output:

.+#++.+#
#.+#++.+
+#.+#++.
Example (Too_wide)
package main

import (
	"fmt"
	"image"
	"os"

	"git.sr.ht/~rj/sgr"
	"git.sr.ht/~rj/sgr/termimage"
)

func main() {
	// Image is 512 pixels wide.
	src := image.NewGray(image.Rect(0, 0, 512, 1))

	f := sgr.NewFormatter()
	err := termimage.DrawImage(os.Stdout, f, src)
	if err != nil {
		fmt.Printf("error: %s\n", err)
	}

}
Output:

error: terminal width is too small for image

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL