blooblib/image.go

96 lines
2.0 KiB
Go

package bloob
import (
"bytes"
_ "github.com/askeladdk/aseprite"
"image"
_ "image/png"
"os"
"runtime/pprof"
"sync"
"unsafe"
)
type Image struct {
Data []Color
Size Vec2i
Alpha bool
}
type Color = uint32
var wg sync.WaitGroup
var threadProfile = pprof.Lookup("threadcreate")
func NewImage(size Vec2i) *Image {
return &Image{Data: make([]Color, size.Size()), Size: Vec2i{X: size.X, Y: size.Y}, Alpha: true}
}
func NewImageFromPointer(pointer unsafe.Pointer, size Vec2i) *Image {
return &Image{Data: unsafe.Slice((*Color)(pointer), size.Size()), Size: Vec2i{X: size.X, Y: size.Y}, Alpha: true}
}
func LoadImage(path string) *Image {
data, err := os.ReadFile(path)
if err != nil {
panic(err)
}
return LoadImageBytes(data)
}
func LoadImageBytes(data []byte) *Image {
file, _, _ := image.Decode(bytes.NewReader(data))
width := file.Bounds().Max.X
height := file.Bounds().Max.Y
img := NewImage(Vec2i{X: width, Y: height})
for y := 0; y < height; y += 1 {
for x := 0; x < width; x += 1 {
r, g, b, a := file.At(x, y).RGBA()
r = r >> 8
g = g >> 8
b = b >> 8
a = a >> 8
img.Data[x+y*width] = r<<16 | g<<8 | b | a<<24
}
}
return img
}
func (image *Image) Clear(color Color) {
for i := 0; i < image.Size.X*image.Size.Y; i += 1 {
image.Data[i] = color
}
}
func CropToArea(sizeDst Vec2i, rectSrc Recti, posDst Vec2i) (start, end, dst Vec2i) {
if posDst.X+rectSrc.Pos.X < 0 {
start.X = -posDst.X
} else {
start.X = rectSrc.Pos.X
}
if posDst.X+rectSrc.Size.X-rectSrc.Pos.X >= sizeDst.X {
end.X = sizeDst.X - posDst.X
} else {
end.X = rectSrc.Pos.X + rectSrc.Size.X
}
if posDst.Y+rectSrc.Pos.Y < 0 {
start.Y = -posDst.Y
} else {
start.Y = rectSrc.Pos.Y
}
if posDst.Y+rectSrc.Size.Y-rectSrc.Pos.Y >= sizeDst.Y {
end.Y = sizeDst.Y - posDst.Y
} else {
end.Y = rectSrc.Pos.Y + rectSrc.Size.Y
}
dst = Sub(posDst, rectSrc.Pos)
//println(dst.X, posDst.X, rectSrc.Pos.X)
return
}
func (image *Image) DrawPixel(pos Vec2i, color Color) {
image.Data[pos.X+pos.Y*image.Size.X] = color
}