Implement --scale-up and --place
This commit is contained in:
parent
73a055fe12
commit
df06578c2d
@ -46,7 +46,9 @@ Choose where on the screen to display the image. The image will be scaled to fit
|
||||
into the specified rectangle. The syntax for specifying rectangles is
|
||||
<:italic:`width`>x<:italic:`height`>@<:italic:`left`>x<:italic:`top`>.
|
||||
All measurements are in cells (i.e. cursor positions) with the origin
|
||||
:italic:`(0, 0)` at the top-left corner of the screen.
|
||||
:italic:`(0, 0)` at the top-left corner of the screen. Note that the :option:`--align`
|
||||
option will horizontally align the image within this rectangle. By default, the image
|
||||
is horizontally centered within the rectangle.
|
||||
|
||||
|
||||
--scale-up
|
||||
|
||||
@ -50,6 +50,15 @@ func load_one_frame_image(imgd *image_data, src *opened_input) (image.Image, err
|
||||
imgd.canvas_height = img.Bounds().Dy()
|
||||
set_basic_metadata(imgd)
|
||||
}
|
||||
if imgd.needs_scaling {
|
||||
if imgd.canvas_width < imgd.available_width && opts.ScaleUp && place != nil {
|
||||
r := float64(imgd.available_width) / float64(imgd.canvas_width)
|
||||
imgd.canvas_width, imgd.canvas_height = imgd.available_width, int(r*float64(imgd.canvas_height))
|
||||
}
|
||||
imgd.canvas_width, imgd.canvas_height = images.FitImage(imgd.canvas_width, imgd.canvas_height, imgd.available_width, imgd.available_height)
|
||||
img = imaging.Resize(img, imgd.canvas_width, imgd.canvas_height, imaging.Lanczos)
|
||||
imgd.needs_scaling = false
|
||||
}
|
||||
return img, err
|
||||
}
|
||||
|
||||
|
||||
@ -151,6 +151,9 @@ type image_data struct {
|
||||
needs_scaling, needs_conversion bool
|
||||
frames []*image_frame
|
||||
image_number uint32
|
||||
cell_x_offset int
|
||||
move_x_by int
|
||||
move_to struct{ x, y int }
|
||||
|
||||
// for error reporting
|
||||
err error
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"kitty/tools/tui/graphics"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/utils/shm"
|
||||
"math"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -22,6 +23,9 @@ func gc_for_image(imgd *image_data, frame_num int, frame *image_frame) *graphics
|
||||
gc.SetAction(graphics.GRT_action_transmit_and_display)
|
||||
gc.SetDataWidth(uint64(frame.width)).SetDataHeight(uint64(frame.height))
|
||||
gc.SetQuiet(graphics.GRT_quiet_silent)
|
||||
if frame_num == 0 && imgd.cell_x_offset > 0 {
|
||||
gc.SetXOffset(uint64(imgd.cell_x_offset))
|
||||
}
|
||||
if z_index != 0 {
|
||||
gc.SetZIndex(z_index)
|
||||
}
|
||||
@ -151,6 +155,44 @@ func transmit_stream(imgd *image_data, frame_num int, frame *image_frame) (err e
|
||||
return nil
|
||||
}
|
||||
|
||||
func calculate_in_cell_x_offset(width, cell_width int) int {
|
||||
extra_pixels := width % cell_width
|
||||
if extra_pixels == 0 {
|
||||
return 0
|
||||
}
|
||||
switch opts.Align {
|
||||
case "left":
|
||||
return 0
|
||||
case "right":
|
||||
return cell_width - extra_pixels
|
||||
default:
|
||||
return (cell_width - extra_pixels) / 2
|
||||
}
|
||||
}
|
||||
|
||||
func place_cursor(imgd *image_data) {
|
||||
cw := int(screen_size.CellWidth)
|
||||
imgd.cell_x_offset = calculate_in_cell_x_offset(imgd.canvas_width, cw)
|
||||
num_of_cells_needed := int(math.Ceil(float64(imgd.canvas_width) / float64(cw)))
|
||||
if place == nil {
|
||||
switch opts.Align {
|
||||
case "center":
|
||||
imgd.move_x_by = (int(screen_size.WidthCells) - num_of_cells_needed) / 2
|
||||
case "right":
|
||||
imgd.move_x_by = (int(screen_size.WidthCells) - num_of_cells_needed)
|
||||
}
|
||||
} else {
|
||||
imgd.move_to.x = place.left + 1
|
||||
imgd.move_to.y = place.top + 1
|
||||
switch opts.Align {
|
||||
case "center":
|
||||
imgd.move_to.x += (place.width - num_of_cells_needed) / 2
|
||||
case "right":
|
||||
imgd.move_to.x += (place.width - num_of_cells_needed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func transmit_image(imgd *image_data) {
|
||||
defer func() {
|
||||
for _, frame := range imgd.frames {
|
||||
@ -189,10 +231,21 @@ func transmit_image(imgd *image_data) {
|
||||
if len(imgd.frames) > 1 {
|
||||
imgd.image_number = rand.Uint32()
|
||||
}
|
||||
place_cursor(imgd)
|
||||
lp.QueueWriteString("\r")
|
||||
if imgd.move_x_by > 0 {
|
||||
lp.MoveCursorHorizontally(imgd.move_x_by)
|
||||
}
|
||||
if imgd.move_to.x > 0 {
|
||||
lp.MoveCursorTo(imgd.move_to.x, imgd.move_to.y)
|
||||
}
|
||||
for frame_num, frame := range imgd.frames {
|
||||
err := f(imgd, frame_num, frame)
|
||||
if err != nil {
|
||||
print_error("Failed to transmit %s with error: %v", imgd.source_name, err)
|
||||
}
|
||||
}
|
||||
if imgd.move_to.x == 0 {
|
||||
lp.Println() // ensure cursor is on new line
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,6 +261,12 @@ func (self *Loop) SetCursorVisible(visible bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Loop) MoveCursorTo(x, y int) {
|
||||
if x > 0 && y > 0 {
|
||||
self.QueueWriteString(fmt.Sprintf("\x1b[%d;%dH", y, x))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Loop) MoveCursorHorizontally(amt int) {
|
||||
if amt != 0 {
|
||||
suffix := "C"
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"math"
|
||||
"runtime"
|
||||
"sync"
|
||||
)
|
||||
@ -390,3 +391,20 @@ func PasteCenter(background image.Image, img image.Image, opaque_bg *color.NRGBA
|
||||
|
||||
Paste(background, img, image.Pt(x0, y0), opaque_bg)
|
||||
}
|
||||
|
||||
func FitImage(width, height, pwidth, pheight int) (final_width int, final_height int) {
|
||||
if height > pheight {
|
||||
corrf := float64(pheight) / float64(height)
|
||||
width, height = int(math.Floor(corrf*float64(width))), pheight
|
||||
}
|
||||
if width > pwidth {
|
||||
corrf := float64(pwidth) / float64(width)
|
||||
width, height = pwidth, int(math.Floor(corrf*float64(height)))
|
||||
}
|
||||
if height > pheight {
|
||||
corrf := float64(pheight) / float64(height)
|
||||
width, height = int(math.Floor(corrf*float64(width))), pheight
|
||||
}
|
||||
|
||||
return width, height
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user