Added tool to color image.

Separated some image related methods.
Added feedback for simulation speed (colored buttons).
This commit is contained in:
Sander Schobers 2020-05-10 17:40:56 +02:00
parent b14f79a61a
commit cd5ca3f04f
14 changed files with 150 additions and 73 deletions

34
cmd/imadapt/color.go Normal file
View File

@ -0,0 +1,34 @@
package main
import (
"image"
"image/color"
"opslag.de/schobers/tins2020/img"
)
func colorImage(path string, col color.Color) error {
src, err := img.DecodeImage(path)
if err != nil {
return err
}
colNRGBA := color.NRGBAModel.Convert(col).(color.NRGBA)
bounds := src.Bounds()
dst := image.NewRGBA(bounds)
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
c := src.At(x, y)
srcCol := color.NRGBAModel.Convert(c).(color.NRGBA)
if srcCol.A > 0 {
dstCol := colNRGBA
dstCol.A = srcCol.A
dst.Set(x, y, dstCol)
} else {
dst.Set(x, y, c)
}
}
}
return img.EncodePNG(path, dst)
return nil
}

View File

@ -5,10 +5,11 @@ import (
"image/draw"
"github.com/nfnt/resize"
"opslag.de/schobers/tins2020/img"
)
func crop(path string, crop rect, size *point) error {
src, err := decodeImage(path)
src, err := img.DecodeImage(path)
if err != nil {
return err
}
@ -17,9 +18,9 @@ func crop(path string, crop rect, size *point) error {
dst := image.NewRGBA(dstRect)
draw.Draw(dst, dstRect, src, srcRect.Min, draw.Src)
if size == nil {
return encodePNG(path, dst)
return img.EncodePNG(path, dst)
}
resized := resize.Resize(uint(size.x), uint(size.y), dst, resize.Bilinear)
return encodePNG(path, resized)
return img.EncodePNG(path, resized)
}

View File

@ -3,10 +3,12 @@ package main
import (
"image"
"image/color"
"opslag.de/schobers/tins2020/img"
)
func convertToGray(path string) error {
src, err := decodeImage(path)
src, err := img.DecodeImage(path)
if err != nil {
return err
}
@ -25,5 +27,5 @@ func convertToGray(path string) error {
}
}
}
return encodePNG(path, dst)
return img.EncodePNG(path, dst)
}

View File

@ -5,6 +5,8 @@ import (
"flag"
"fmt"
"log"
"opslag.de/schobers/tins2020/img"
)
func run() error {
@ -73,6 +75,17 @@ func run() error {
return fmt.Errorf("couldn't crop '%s'; error: %v", path, err)
}
}
case "color":
flags := flag.NewFlagSet("color", flag.ContinueOnError)
var col string
flags.StringVar(&col, "color", "#ff0000", "target color")
flags.Parse(args[1:])
for _, path := range flags.Args() {
err := colorImage(path, img.MustHexColor(col))
if err != nil {
return fmt.Errorf("couldn't convert to grayscale of '%s'; error: %v", path, err)
}
}
}
return nil
}

View File

@ -3,10 +3,12 @@ package main
import (
"image"
"image/color"
"opslag.de/schobers/tins2020/img"
)
func setAlpha(path string, alpha int) error {
src, err := decodeImage(path)
src, err := img.DecodeImage(path)
if err != nil {
return err
}
@ -21,5 +23,5 @@ func setAlpha(path string, alpha int) error {
dst.Set(x, y, c)
}
}
return encodePNG(path, dst)
return img.EncodePNG(path, dst)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

View File

@ -8,8 +8,11 @@ control-load: images/basket.png
control-quit: images/power.png
control-pause: images/pause.png
control-pause-disabled: images/pause_disabled.png
control-run: images/forward.png
control-run-disabled: images/forward_disabled.png
control-run-fast: images/fastForward.png
control-run-fast-disabled: images/fastForward_disabled.png
tile-dirt: images/tile_dirt.png
tile-grass: images/tile_grass.png

View File

@ -1,63 +1,9 @@
package tins2020
import (
"errors"
"regexp"
"opslag.de/schobers/tins2020/img"
"github.com/veandco/go-sdl2/sdl"
)
var hexColorRE = regexp.MustCompile(`^#?([0-9A-Fa-f]{2})-?([0-9A-Fa-f]{2})-?([0-9A-Fa-f]{2})-?([0-9A-Fa-f]{2})?$`)
func HexColor(s string) (sdl.Color, error) {
match := hexColorRE.FindStringSubmatch(s)
if match == nil {
return sdl.Color{}, errors.New("invalid color format")
}
values, err := HexToInts(match[1:]...)
if err != nil {
return sdl.Color{}, err
}
a := 255
if len(match[4]) > 0 {
a = values[3]
}
return sdl.Color{R: uint8(values[0]), G: uint8(values[1]), B: uint8(values[2]), A: uint8(a)}, nil
}
func MustHexColor(s string) sdl.Color {
color, err := HexColor(s)
if err != nil {
panic(err)
}
return color
}
func HexToInt(s string) (int, error) {
var i int
for _, c := range s {
i *= 16
if c >= '0' && c <= '9' {
i += int(c - '0')
} else if c >= 'A' && c <= 'F' {
i += int(c - 'A' + 10)
} else if c >= 'a' && c <= 'f' {
i += int(c - 'a' + 10)
} else {
return 0, errors.New("hex digit not supported")
}
}
return i, nil
}
func HexToInts(s ...string) ([]int, error) {
ints := make([]int, len(s))
for i, s := range s {
value, err := HexToInt(s)
if err != nil {
return nil, err
}
ints[i] = value
}
return ints, nil
}
func MustHexColor(s string) sdl.Color { return sdl.Color(img.MustHexColor(s)) }

View File

@ -58,6 +58,7 @@ func NewGame() *Game {
}
terrain.AddFlower(Pt(0, 0), NewPoppyTraits())
return &Game{
Speed: GameSpeedNormal,
Balance: 100,
Terrain: terrain,

View File

@ -19,6 +19,12 @@ func NewGameControls(game *Game) *GameControls {
}
func (c *GameControls) updateSpeedControls() {
disable := func(b *IconButton, speed GameSpeed) {
b.IsDisabled = speed == c.game.Speed
}
disable(c.pause, GameSpeedPaused)
disable(c.run, GameSpeedNormal)
disable(c.runFast, GameSpeedFast)
}
func (c *GameControls) Arrange(ctx *Context, bounds Rectangle) {
@ -40,18 +46,25 @@ func (c *GameControls) Init(ctx *Context) error {
}
c.top.Orientation = OrientationHorizontal
c.pause = NewIconButton("control-pause", EmptyEvent(func() {
c.pause = NewIconButtonConfig("control-pause", EmptyEvent(func() {
c.game.Pause()
c.updateSpeedControls()
}))
c.run = NewIconButton("control-run", EmptyEvent(func() {
}), func(b *IconButton) {
b.IconDisabled = "control-pause-disabled"
})
c.run = NewIconButtonConfig("control-run", EmptyEvent(func() {
c.game.Run()
c.updateSpeedControls()
}))
c.runFast = NewIconButton("control-run-fast", EmptyEvent(func() {
}), func(b *IconButton) {
b.IconDisabled = "control-run-disabled"
})
c.runFast = NewIconButtonConfig("control-run-fast", EmptyEvent(func() {
c.game.RunFast()
c.updateSpeedControls()
}))
}), func(b *IconButton) {
b.IconDisabled = "control-run-fast-disabled"
})
c.updateSpeedControls()
c.top.Buttons = []Control{c.pause, c.run, c.runFast}
c.menu.Background = MustHexColor("#356dad")
@ -71,7 +84,7 @@ func (c *GameControls) Render(ctx *Context) {
topBar := MustHexColor("#0000007f")
ctx.Renderer.SetDrawColor(topBar.R, topBar.G, topBar.B, topBar.A)
ctx.Renderer.FillRect(Rect(c.menu.Bounds.Right(), 0, c.flowers.Bounds.X, 64).SDLPtr())
ctx.Fonts.Font("balance").RenderCopyAlign(ctx.Renderer, FmtMoney(c.game.Balance), Pt(c.top.Bounds.X-8, 58), MustHexColor("#79A6D9"), TextAlignmentRight)
ctx.Fonts.Font("balance").RenderCopyAlign(ctx.Renderer, FmtMoney(c.game.Balance), Pt(c.top.Bounds.X-8, 58), MustHexColor("#4AC69A"), TextAlignmentRight)
c.Container.Render(ctx)
}

62
img/color.go Normal file
View File

@ -0,0 +1,62 @@
package img
import (
"errors"
"image/color"
"regexp"
)
var hexColorRE = regexp.MustCompile(`^#?([0-9A-Fa-f]{2})-?([0-9A-Fa-f]{2})-?([0-9A-Fa-f]{2})-?([0-9A-Fa-f]{2})?$`)
func HexColor(s string) (color.RGBA, error) {
match := hexColorRE.FindStringSubmatch(s)
if match == nil {
return color.RGBA{}, errors.New("invalid color format")
}
values, err := HexToInts(match[1:]...)
if err != nil {
return color.RGBA{}, err
}
a := 255
if len(match[4]) > 0 {
a = values[3]
}
return color.RGBA{R: uint8(values[0]), G: uint8(values[1]), B: uint8(values[2]), A: uint8(a)}, nil
}
func MustHexColor(s string) color.RGBA {
color, err := HexColor(s)
if err != nil {
panic(err)
}
return color
}
func HexToInt(s string) (int, error) {
var i int
for _, c := range s {
i *= 16
if c >= '0' && c <= '9' {
i += int(c - '0')
} else if c >= 'A' && c <= 'F' {
i += int(c - 'A' + 10)
} else if c >= 'a' && c <= 'f' {
i += int(c - 'a' + 10)
} else {
return 0, errors.New("hex digit not supported")
}
}
return i, nil
}
func HexToInts(s ...string) ([]int, error) {
ints := make([]int, len(s))
for i, s := range s {
value, err := HexToInt(s)
if err != nil {
return nil, err
}
ints[i] = value
}
return ints, nil
}

View File

@ -1,4 +1,4 @@
package main
package img
import (
"image"
@ -6,7 +6,7 @@ import (
"os"
)
func encodePNG(path string, im image.Image) error {
func EncodePNG(path string, im image.Image) error {
dst, err := os.Create(path)
if err != nil {
return err
@ -15,7 +15,7 @@ func encodePNG(path string, im image.Image) error {
return png.Encode(dst, im)
}
func decodeImage(path string) (image.Image, error) {
func DecodeImage(path string) (image.Image, error) {
f, err := os.Open(path)
if err != nil {
return nil, err