github.com/xyproto/orbiton/v2@v2.65.12-0.20240516144430-e10a419274ec/image.go (about) 1 package main 2 3 import ( 4 "errors" 5 "fmt" 6 "image" 7 "path/filepath" 8 9 "github.com/xyproto/carveimg" 10 "github.com/xyproto/vt100" 11 "golang.org/x/image/draw" 12 ) 13 14 // var imageResizeFunction = draw.NearestNeighbor 15 // var imageResizeFunction = draw.ApproxBiLinear 16 // var imageResizeFunction = draw.BiLinear 17 var imageResizeFunction = draw.CatmullRom 18 19 func displayImage(c *vt100.Canvas, filename string, waitForKeypress bool) error { 20 // Find the width and height of the canvas 21 width := int(c.Width()) 22 height := int(c.Height()) 23 24 // Load the given filename 25 nImage, err := carveimg.LoadImage(filename) 26 if err != nil { 27 vt100.Close() 28 return fmt.Errorf("could not load %s: %s", filename, err) 29 } 30 31 imageHeight := nImage.Bounds().Max.Y - nImage.Bounds().Min.Y 32 imageWidth := nImage.Bounds().Max.X - nImage.Bounds().Min.X 33 if imageWidth == 0 { 34 return errors.New("the width of the given image is 0") 35 } 36 37 ratio := (float64(imageHeight) / float64(imageWidth)) * 4.0 // terminal "pixels" are a bit narrow, so multiply by 4.0 38 if ratio == 0 { 39 return errors.New("the ratio of the given image is 0") 40 } 41 42 // Use a smaller width, if that makes the image more like the original proportions 43 proportionalWidth := int(float64(height) * ratio) 44 if proportionalWidth < width { 45 width = proportionalWidth 46 } 47 48 // Set the desired size to the size of the current terminal emulator 49 resizedImage := image.NewRGBA(image.Rect(0, 0, width, height)) 50 51 // Resize the image 52 imageResizeFunction.Scale(resizedImage, resizedImage.Rect, nImage, nImage.Bounds(), draw.Over, nil) 53 54 // Draw the image to the canvas, using only the basic 16 colors 55 if err := carveimg.Draw(c, resizedImage); err != nil { 56 vt100.Close() 57 return fmt.Errorf("could not draw image: %s", err) 58 } 59 60 // Output the filename on top of the image 61 title := " " + filepath.Base(filename) + " " 62 c.Write(uint((width-len(title))/2), uint(height-1), vt100.Black, vt100.BackgroundGray, title) 63 64 // Draw the contents of the canvas to the screen 65 c.Draw() 66 67 // Hide the cursor 68 vt100.ShowCursor(false) 69 defer vt100.ShowCursor(true) 70 71 if waitForKeypress { 72 // Wait for a keypress 73 vt100.WaitForKey() 74 } 75 76 return nil 77 }