cmd
This commit is contained in:
58
cmd/downscale2x/downscale.go
Normal file
58
cmd/downscale2x/downscale.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
var errOutOfBounds error = errors.New("downscale: out of bounds")
|
||||||
|
|
||||||
|
type Downscaled struct {
|
||||||
|
image.Image
|
||||||
|
Factor int
|
||||||
|
}
|
||||||
|
|
||||||
|
func isOutOfBounds(pt image.Point, img image.Image) bool {
|
||||||
|
x, y := img.Bounds().Dx(), img.Bounds().Dy()
|
||||||
|
if pt.X > x || pt.Y > y {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func meanColor(palette color.Palette) color.Color {
|
||||||
|
var r, g, b int
|
||||||
|
for _, v := range palette {
|
||||||
|
c := color.RGBAModel.Convert(v).(color.RGBA)
|
||||||
|
r += int(c.R)
|
||||||
|
g += int(c.G)
|
||||||
|
b += int(c.B)
|
||||||
|
}
|
||||||
|
r, g, b = r/len(palette), g/len(palette), b/len(palette)
|
||||||
|
return color.RGBA{uint8(r), uint8(g), uint8(b), 0xff}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Downscaled) ColorModel() color.Model { return d.Image.ColorModel() }
|
||||||
|
func (d Downscaled) Bounds() image.Rectangle {
|
||||||
|
return image.Rect(0, 0, d.Image.Bounds().Dx()/d.Factor, d.Image.Bounds().Dy()/d.Factor)
|
||||||
|
}
|
||||||
|
func (d Downscaled) At(x, y int) color.Color {
|
||||||
|
palette := color.Palette{}
|
||||||
|
pt := image.Point{x * d.Factor, y * d.Factor}
|
||||||
|
if isOutOfBounds(pt, d.Image) {
|
||||||
|
panic(errOutOfBounds)
|
||||||
|
}
|
||||||
|
for i := 0; i < d.Factor; i++ {
|
||||||
|
for j := 0; j < d.Factor; j++ {
|
||||||
|
currentPt := image.Point{pt.X + i, pt.Y + j}
|
||||||
|
if i > 0 || j > 0 {
|
||||||
|
if isOutOfBounds(currentPt, d.Image) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
palette = append(palette, d.Image.At(currentPt.X, currentPt.Y))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return palette.Convert(meanColor(palette))
|
||||||
|
}
|
||||||
21
cmd/downscale2x/main.go
Normal file
21
cmd/downscale2x/main.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/jpeg"
|
||||||
|
"image/png"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// open image
|
||||||
|
img, err := jpeg.Decode(os.Stdin)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// no pre-processing needed so we just
|
||||||
|
// write image
|
||||||
|
err = png.Encode(os.Stdout, Downscaled{img, 3})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
cmd/mesh/8.clock.png
Normal file
BIN
cmd/mesh/8.clock.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
41
cmd/mesh/9p.go
Normal file
41
cmd/mesh/9p.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
//go:build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func ListenAndServe(addr string, filesystem fs.FS) error {
|
||||||
|
styx.HandlerFunc(func(s *styx.Session) {
|
||||||
|
for s.Next() {
|
||||||
|
switch msg := s.Request.(type) {
|
||||||
|
case styx.Twalk:
|
||||||
|
msg.Rwalk(fs.Stat(filesystem, msg.Path()))
|
||||||
|
case styx.Topen:
|
||||||
|
msg.Ropen(filesystem.Open(msg.Path()))
|
||||||
|
case styx.Tstat:
|
||||||
|
msg.Rstat(fs.Stat(filesystem, msg.Path()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type FS struct {
|
||||||
|
meshFile
|
||||||
|
}
|
||||||
|
|
||||||
|
type meshFile struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type meshFileInfo struct {
|
||||||
|
bufio.Reader
|
||||||
|
time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f meshFileInfo) Name() string { return "mesh" }
|
||||||
|
func (f meshFileInfo) Size() int64 { return f.Reader.Size() }
|
||||||
|
func (f meshFileInfo) Mode() fs.FileMode { return fs.ModePerm }
|
||||||
|
func (f meshFileInfo) ModTime() time.Time { return f.Time }
|
||||||
|
func (f meshFileInfo) IsDir() bool { return false }
|
||||||
|
func (f meshFileInfo) Sys() any { return nil }
|
||||||
|
|
||||||
|
func (f meshFile) Stat() (fs.FileInfo, error) {
|
||||||
|
}
|
||||||
91
cmd/mesh/mesh.go
Normal file
91
cmd/mesh/mesh.go
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
|
"image/png"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/freetype/truetype"
|
||||||
|
"golang.org/x/image/font"
|
||||||
|
"golang.org/x/image/font/gofont/gomono"
|
||||||
|
"golang.org/x/image/math/fixed"
|
||||||
|
// "github.com/droyo/styx"
|
||||||
|
// "io/fs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Mesh struct {
|
||||||
|
image.Image
|
||||||
|
X, Y int // divide
|
||||||
|
}
|
||||||
|
|
||||||
|
// using source's color.Model
|
||||||
|
func (mesh Mesh) ColorModel() color.Model { return mesh.Image.ColorModel() }
|
||||||
|
|
||||||
|
// using source's image.Rectangle
|
||||||
|
func (mesh Mesh) Bounds() image.Rectangle { return mesh.Image.Bounds() }
|
||||||
|
func (mesh Mesh) At(x, y int) color.Color {
|
||||||
|
dx, dy := mesh.Image.Bounds().Dx(), mesh.Image.Bounds().Dy()
|
||||||
|
if (x%(dx/mesh.X)) == 0 || (y%(dy/mesh.Y)) == 0 {
|
||||||
|
return color.Black
|
||||||
|
}
|
||||||
|
return mesh.Image.At(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
func render(img image.Image) draw.Image {
|
||||||
|
dst := image.NewRGBA(img.Bounds())
|
||||||
|
draw.Draw(dst, dst.Bounds(), img, image.Point{}, draw.Src)
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// x := flag.Int("x", 2, "use to grid by x axis")
|
||||||
|
// y := flag.Int("y", 2, "use to grid by y axis")
|
||||||
|
flag.Parse() // now flags is ready to use
|
||||||
|
|
||||||
|
img, err := png.Decode(os.Stdin)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// Mesh{ // our image modifyer
|
||||||
|
// Image: img,
|
||||||
|
// X: *x,
|
||||||
|
// Y: *y,
|
||||||
|
// },
|
||||||
|
|
||||||
|
dst := render(
|
||||||
|
img,
|
||||||
|
)
|
||||||
|
|
||||||
|
f, err := truetype.Parse(gomono.TTF)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
face := truetype.NewFace(f, &truetype.Options{
|
||||||
|
Size: float64(img.Bounds().Dx() / 19),
|
||||||
|
DPI: 72,
|
||||||
|
Hinting: font.HintingNone,
|
||||||
|
})
|
||||||
|
|
||||||
|
d := &font.Drawer{
|
||||||
|
Dst: dst,
|
||||||
|
Src: image.NewUniform(color.Black),
|
||||||
|
Face: face,
|
||||||
|
Dot: fixed.Point26_6{fixed.Int26_6(img.Bounds().Dx() /
|
||||||
|
9*64,
|
||||||
|
),
|
||||||
|
fixed.Int26_6(img.Bounds().Dy() /
|
||||||
|
5*64,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
d.DrawString(time.Now().Format(time.Kitchen))
|
||||||
|
|
||||||
|
err = png.Encode(os.Stdout, dst)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
67
cmd/mkpalette/palette.go
Normal file
67
cmd/mkpalette/palette.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/csv"
|
||||||
|
"fmt"
|
||||||
|
"image/color"
|
||||||
|
"image/png"
|
||||||
|
"maps"
|
||||||
|
"os"
|
||||||
|
"slices"
|
||||||
|
|
||||||
|
imgutil "git.niplace.ru/XoxJlopeZi4BB/imageutils/pkg"
|
||||||
|
)
|
||||||
|
|
||||||
|
func check(err error) {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Set[S comparable] map[S]struct{}
|
||||||
|
|
||||||
|
func (s Set[S]) Add(v S) {
|
||||||
|
s[v] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Set[S]) Contains(v S) bool {
|
||||||
|
_, ok := s[v]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func Map[S1 ~[]T1, S2 ~[]T2, T1, T2 any](s S1, f func(T1) T2) S2 {
|
||||||
|
result := make(S2, len(s))
|
||||||
|
for i := range s {
|
||||||
|
result[i] = f(s[i])
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
type hex string
|
||||||
|
|
||||||
|
func (h hex) String() string {
|
||||||
|
return string(fmt.Sprintf("hex value: %s\n", string(h)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
img, err := png.Decode(os.Stdin)
|
||||||
|
check(err)
|
||||||
|
p := Set[color.Color]{}
|
||||||
|
for y := 0; y < img.Bounds().Dy(); y++ {
|
||||||
|
for x := 0; x < img.Bounds().Dx(); x++ {
|
||||||
|
p.Add(img.At(x, y))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w := csv.NewWriter(os.Stdout)
|
||||||
|
s := Map[color.Palette, []string](
|
||||||
|
slices.Collect(maps.Keys(p)), imgutil.ColorToHex,
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
h := make([]hex, 0, len(s))
|
||||||
|
for i := range s {
|
||||||
|
h = append(h, hex(s[i]))
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
err = w.Write(s)
|
||||||
|
check(err)
|
||||||
|
}
|
||||||
BIN
cmd/negate/8.absolutecinema.png
Normal file
BIN
cmd/negate/8.absolutecinema.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
BIN
cmd/negate/minus19blue
Executable file
BIN
cmd/negate/minus19blue
Executable file
Binary file not shown.
39
cmd/negate/minus19blue.go
Normal file
39
cmd/negate/minus19blue.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
//go:build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/png"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Reshade struct{ image.Image }
|
||||||
|
|
||||||
|
func (rs Reshade) ColorModel() color.Model { return rs.Image.ColorModel() }
|
||||||
|
func (rs Reshade) Bounds() image.Rectangle { return rs.Image.Bounds() }
|
||||||
|
func (rs Reshade) At(x, y int) color.Color {
|
||||||
|
c := rs.Image.At(x, y)
|
||||||
|
r, g, b, a := c.RGBA()
|
||||||
|
// minus 19 blue
|
||||||
|
return color.RGBA{
|
||||||
|
uint8(r >> 8),
|
||||||
|
uint8(g >> 8),
|
||||||
|
uint8(b>>8) - 8*8,
|
||||||
|
uint8(a >> 8),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func check(err error) {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
img, err := png.Decode(os.Stdin)
|
||||||
|
check(err)
|
||||||
|
err = png.Encode(os.Stdout, Reshade{img})
|
||||||
|
check(err)
|
||||||
|
}
|
||||||
70
cmd/negate/mixed.go
Normal file
70
cmd/negate/mixed.go
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/png"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MixedNegation struct {
|
||||||
|
src image.Image
|
||||||
|
counter int
|
||||||
|
}
|
||||||
|
|
||||||
|
func toRGBA(c color.Color) color.RGBA {
|
||||||
|
r, g, b, a := c.RGBA()
|
||||||
|
return color.RGBA{
|
||||||
|
R: uint8(r >> 8),
|
||||||
|
G: uint8(g >> 8),
|
||||||
|
B: uint8(b >> 8),
|
||||||
|
A: uint8(a >> 8),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func negateRGBA(c color.RGBA) color.RGBA {
|
||||||
|
c.R = 255 - c.R
|
||||||
|
c.G = 255 - c.G
|
||||||
|
c.B = 255 - c.B
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func Negate(c color.Color) color.Color {
|
||||||
|
return negateRGBA(toRGBA(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
func randomBool() bool {
|
||||||
|
return rand.Intn(3) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mn MixedNegation) ColorModel() color.Model { return mn.src.ColorModel() }
|
||||||
|
func (mn MixedNegation) Bounds() image.Rectangle { return mn.src.Bounds() }
|
||||||
|
func (mn *MixedNegation) At(x, y int) color.Color {
|
||||||
|
if (x%1 != 0) && (y%8 != 0) {
|
||||||
|
if randomBool() {
|
||||||
|
return Negate(mn.src.At(x, y))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return mn.src.At(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
func pixelCount(img image.Image) int {
|
||||||
|
return img.Bounds().Dx() * img.Bounds().Dy()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
img, err := png.Decode(os.Stdin)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
n := pixelCount(img)
|
||||||
|
println(n)
|
||||||
|
|
||||||
|
err = png.Encode(os.Stdout, &MixedNegation{src: img, counter: n})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
cmd/negate/negate
Executable file
BIN
cmd/negate/negate
Executable file
Binary file not shown.
44
cmd/negate/negate.go
Normal file
44
cmd/negate/negate.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/png"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NegateRGBA(c color.RGBA) color.RGBA {
|
||||||
|
c.R = 255 - c.R
|
||||||
|
c.G = 255 - c.G
|
||||||
|
c.B = 255 - c.B
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type Negate struct{ image.Image }
|
||||||
|
|
||||||
|
func (n Negate) ColorModel() color.Model { return n.Image.ColorModel() }
|
||||||
|
func (n Negate) Bounds() image.Rectangle { return n.Image.Bounds() }
|
||||||
|
func (n Negate) At(x, y int) color.Color {
|
||||||
|
c := n.Image.At(x, y)
|
||||||
|
r, g, b, a := c.RGBA()
|
||||||
|
RGBAColor := color.RGBA{
|
||||||
|
R: uint8(r >> 8),
|
||||||
|
G: uint8(g >> 8),
|
||||||
|
B: uint8(b >> 8),
|
||||||
|
A: uint8(a >> 8),
|
||||||
|
}
|
||||||
|
return NegateRGBA(RGBAColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func check(err error) {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
img, err := png.Decode(os.Stdin)
|
||||||
|
check(err)
|
||||||
|
err = png.Encode(os.Stdout, Negate{img})
|
||||||
|
check(err)
|
||||||
|
}
|
||||||
BIN
cmd/negate/negated5.png
Normal file
BIN
cmd/negate/negated5.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 977 KiB |
BIN
cmd/negate/negated8.png
Normal file
BIN
cmd/negate/negated8.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
BIN
cmd/negate/reshaded,negated8.png
Normal file
BIN
cmd/negate/reshaded,negated8.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
BIN
cmd/showpalette/.show.go.swp
Normal file
BIN
cmd/showpalette/.show.go.swp
Normal file
Binary file not shown.
74
cmd/showpalette/show.go
Normal file
74
cmd/showpalette/show.go
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/csv"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/png"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
imgutil "git.niplace.ru/XoxJlopeZi4BB/imageutils/pkg"
|
||||||
|
)
|
||||||
|
|
||||||
|
func nearestHighSqrt(n int) int {
|
||||||
|
if math.Mod(math.Sqrt(float64(n)), 1) == 0 {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
return nearestHighSqrt(n + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
type showColors struct {
|
||||||
|
color.Palette
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s showColors) ColorModel() color.Model {
|
||||||
|
return color.RGBAModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s showColors) Bounds() image.Rectangle {
|
||||||
|
n := nearestHighSqrt(len(s.Palette))
|
||||||
|
return image.Rect(0, 0, n, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s showColors) At(x, y int) color.Color {
|
||||||
|
n := nearestHighSqrt(len(s.Palette))
|
||||||
|
return s.Palette[y*n+x]
|
||||||
|
}
|
||||||
|
|
||||||
|
func check(err error) {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Must[T any](v T, err error) T {
|
||||||
|
check(err)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func Map[S1 ~[]T1, S2 ~[]T2, T1, T2 any](s S1, f func(T1) T2) S2 {
|
||||||
|
result := make(S2, len(s))
|
||||||
|
for i := range s {
|
||||||
|
result[i] = f(s[i])
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
r := csv.NewReader(os.Stdin)
|
||||||
|
r.TrailingComma = true
|
||||||
|
colors, err := r.Read()
|
||||||
|
check(err)
|
||||||
|
palette := color.Palette(
|
||||||
|
Map[[]string, color.Palette](colors,
|
||||||
|
func(v string) color.Color {
|
||||||
|
println(v + "cat-v")
|
||||||
|
return Must(imgutil.ParseHexColor(v))
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
err = png.Encode(os.Stdout, showColors{palette})
|
||||||
|
check(err)
|
||||||
|
}
|
||||||
12
go.mod
12
go.mod
@@ -1,5 +1,13 @@
|
|||||||
module git.niplace.ru/XoxJlopeZi4BB/imageutils
|
module git.niplace.ru/XoxJlopeZi4BB/imageutils
|
||||||
|
|
||||||
go 1.22.6
|
go 1.24.0
|
||||||
|
|
||||||
require github.com/potassium5703/texture v0.0.0-20240820054037-fce43fc4b0f0 // indirect
|
require (
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
|
||||||
|
golang.org/x/image v0.33.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
9fans.net/go v0.0.7 // indirect
|
||||||
|
github.com/potassium5703/texture v0.0.0-20240820054037-fce43fc4b0f0 // indirect
|
||||||
|
)
|
||||||
|
|||||||
38
go.sum
38
go.sum
@@ -1,2 +1,40 @@
|
|||||||
|
9fans.net/go v0.0.7 h1:H5CsYJTf99C8EYAQr+uSoEJnLP/iZU8RmDuhyk30iSM=
|
||||||
|
9fans.net/go v0.0.7/go.mod h1:Rxvbbc1e+1TyGMjAvLthGTyO97t+6JMQ6ly+Lcs9Uf0=
|
||||||
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||||
github.com/potassium5703/texture v0.0.0-20240820054037-fce43fc4b0f0 h1:sowjIIVme5ovcdB0kjP3w+4xbVNrlOPdx7Up4LIGJz8=
|
github.com/potassium5703/texture v0.0.0-20240820054037-fce43fc4b0f0 h1:sowjIIVme5ovcdB0kjP3w+4xbVNrlOPdx7Up4LIGJz8=
|
||||||
github.com/potassium5703/texture v0.0.0-20240820054037-fce43fc4b0f0/go.mod h1:KwM7hMpZhr3XySWuK/SZ7s1BXVQe8p1IyZftYg9KtWY=
|
github.com/potassium5703/texture v0.0.0-20240820054037-fce43fc4b0f0/go.mod h1:KwM7hMpZhr3XySWuK/SZ7s1BXVQe8p1IyZftYg9KtWY=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
|
||||||
|
golang.org/x/exp v0.0.0-20210405174845-4513512abef3/go.mod h1:I6l2HNBLBZEcrOoCpyKLdY2lHoRZ8lI4x60KMCQDft4=
|
||||||
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/image v0.33.0 h1:LXRZRnv1+zGd5XBUVRFmYEphyyKJjQjCRiOuAP3sZfQ=
|
||||||
|
golang.org/x/image v0.33.0/go.mod h1:DD3OsTYT9chzuzTQt+zMcOlBHgfoKQb1gry8p76Y1sc=
|
||||||
|
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
|
golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
||||||
|
golang.org/x/mobile v0.0.0-20210220033013-bdb1ca9a1e08/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
||||||
|
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||||
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
|
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210415045647-66c3f260301c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
|
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|||||||
BIN
pkg/.hex_test.go.swp
Normal file
BIN
pkg/.hex_test.go.swp
Normal file
Binary file not shown.
32
pkg/hex.go
Normal file
32
pkg/hex.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package imageutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image/color"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ParseHexColorErr = errors.New("invalid length, must be 7 or 4")
|
||||||
|
|
||||||
|
func ParseHexColor(s string) (c color.RGBA, err error) {
|
||||||
|
c.A = 0xff
|
||||||
|
switch len(s) {
|
||||||
|
case 7:
|
||||||
|
_, err = fmt.Sscanf(s, "#%02x%02x%02x", &c.R, &c.G, &c.B)
|
||||||
|
case 4:
|
||||||
|
_, err = fmt.Sscanf(s, "#%1x%1x%1x", &c.R, &c.G, &c.B)
|
||||||
|
// Double the hex digits:
|
||||||
|
c.R *= 17
|
||||||
|
c.G *= 17
|
||||||
|
c.B *= 17
|
||||||
|
default:
|
||||||
|
err = ParseHexColorErr
|
||||||
|
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func ColorToHex(c color.Color) string {
|
||||||
|
r, g, b, _ := color.NRGBAModel.Convert(c).RGBA()
|
||||||
|
return fmt.Sprintf("#%02x%02x%02x", byte(r), byte(g), byte(b))
|
||||||
|
}
|
||||||
47
pkg/hex_test.go
Normal file
47
pkg/hex_test.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package imageutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image/png"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Returns path of first occured file
|
||||||
|
// with png extension in user's home directory.
|
||||||
|
func firstPNG(root string) (filename string,
|
||||||
|
err error) {
|
||||||
|
var fn filepath.WalkFunc = func(path string,
|
||||||
|
info os.FileInfo,
|
||||||
|
fileErr error) error {
|
||||||
|
if fileErr != nil {
|
||||||
|
return fileErr
|
||||||
|
}
|
||||||
|
if !info.IsDir() &&
|
||||||
|
filepath.Ext(path) == ".png" {
|
||||||
|
filename = path
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err = filepath.Walk(root, fn)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestColorToHex(t *testing.T) {
|
||||||
|
root := os.Getenv("HOME")
|
||||||
|
path, err := firstPNG(root)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
img, err := png.Decode(f)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Println(ColorToHex(img.At(0, 0)))
|
||||||
|
}
|
||||||
1
shakalizator.go
Normal file
1
shakalizator.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package imageutils
|
||||||
Reference in New Issue
Block a user