repl: add scale, rotate

This commit is contained in:
Norwin 2022-01-02 08:07:49 +01:00
parent 69bb57a560
commit a83be54502
3 changed files with 55 additions and 7 deletions

View File

@ -6,6 +6,7 @@ import (
_ "image/gif" // register gif, jpeg, png format handlers
_ "image/jpeg"
"image/png"
"math"
"os"
"golang.org/x/image/draw"
@ -63,10 +64,28 @@ func ImgColorFilter(img *image.NRGBA, from, to color.NRGBA) *image.NRGBA {
return r
}
func ScaleImage(img image.Image, factor int) (scaled *image.NRGBA) {
func ScaleImage(img image.Image, factorX, factorY float64, highQuality bool) (scaled *image.NRGBA) {
b := img.Bounds()
scaledBounds := image.Rect(0, 0, b.Max.X*factor, b.Max.Y*factor)
newX := int(math.Ceil(factorX * float64(b.Max.X)))
newY := int(math.Ceil(factorY * float64(b.Max.Y)))
scaledBounds := image.Rect(0, 0, newX, newY)
scaledImg := image.NewNRGBA(scaledBounds)
draw.NearestNeighbor.Scale(scaledImg, scaledBounds, img, b, draw.Src, nil)
scaler := draw.NearestNeighbor
if highQuality {
scaler = draw.CatmullRom
}
scaler.Scale(scaledImg, scaledBounds, img, b, draw.Src, nil)
return scaledImg
}
func RotateImage90(img *image.NRGBA) (rotated *image.NRGBA) {
b := img.Bounds()
rotated = image.NewNRGBA(image.Rect(0, 0, b.Max.Y, b.Max.X))
for x := b.Min.X; x < b.Max.X; x++ {
for y := b.Min.Y; y < b.Max.Y; y++ {
col := img.NRGBAAt(x, y)
rotated.SetNRGBA(b.Max.Y-y, x, col)
}
}
return
}

View File

@ -16,7 +16,7 @@ func pt(p fixed.Point26_6) image.Point {
}
}
func RenderText(text string, scale int, texture, bgTex image.Image) *image.NRGBA {
func RenderText(text string, scale float64, texture, bgTex image.Image) *image.NRGBA {
face := basicfont.Face7x13
stringBounds, _ := font.BoundString(face, text)
@ -38,5 +38,5 @@ func RenderText(text string, scale int, texture, bgTex image.Image) *image.NRGBA
img.Rect = img.Bounds().Sub(img.Bounds().Min)
// scale up, as this font is quite small
return ScaleImage(img, scale)
return ScaleImage(img, scale, scale, false)
}

View File

@ -28,7 +28,7 @@ const textMode = "txt"
// RunREPL starts reading os.Stdin for commands to apply to the given Fluter
func RunREPL(f Fluter) {
mode := commandMode
textSize := 10
textSize := 10.0
var textCol image.Image = image.White
var bgCol image.Image = image.Transparent
@ -109,7 +109,7 @@ func RunREPL(f Fluter) {
case "txt":
if len(args) > 0 {
if size, err := strconv.Atoi(args[0]); err == nil {
textSize = size
textSize = float64(size)
}
}
if len(args) > 1 {
@ -138,6 +138,33 @@ func RunREPL(f Fluter) {
}
}
case "scale", "s":
quality := true
var facX, facY float64
var err error
if len(args) >= 1 {
facX, err = strconv.ParseFloat(args[0], 64)
if err != nil {
fmt.Println(err)
continue
}
facY = facX
if len(args) >= 2 {
facY, err = strconv.ParseFloat(args[1], 64)
if err != nil {
fmt.Println(err)
continue
}
}
if len(args) > 2 {
quality = false
}
t.Img = render.ScaleImage(t.Img, facX, facY, quality)
}
case "rotate", "r":
t.Img = render.RotateImage90(t.Img)
// the commands below don't affect the task, so we don't need to apply it to clients -> continue
case "metrics":
@ -176,6 +203,8 @@ func printHelp() {
i <filepath> set image
txt <scale> <color <bgcolor> <txt> send text
txt [<scale> [<color> [<bgcolor>]] enter interactive text mode
scale <facX> [<facY> [lofi]] scale content
rotate rotate content 90°
draw modes
o set order (l,r,t,b,random)
of <x> <y> set top-left offset