This commit is contained in:
2026-03-29 17:03:48 +03:00
parent 7143e96ef3
commit 3880b353c1
20 changed files with 491 additions and 23 deletions

22
cmd/dither/main.go Normal file
View File

@@ -0,0 +1,22 @@
package main
import (
"flag"
"image"
"git.nkpl.cc/twocookedfaggots/imageutils/pkg/dithering"
"git.nkpl.cc/twocookedfaggots/imageutils/util"
)
var factor = flag.Float64("n", 0.75, "dithering effect 'magic' number")
func main() {
flag.Parse()
println(*factor)
if err := util.ProcessStdio(func(img image.Image) image.Image {
return dithering.Dithering{img, *factor}
}); err != nil {
panic(err)
}
}

39
cmd/negate/negate.go Normal file
View File

@@ -0,0 +1,39 @@
package main
import (
"image"
"image/color"
"git.nkpl.cc/twocookedfaggots/imageutils/util"
)
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 main() {
if err := util.ProcessStdio(func(img image.Image) image.Image {
return Negate{img}
}); err != nil {
panic(err)
}
}

20
cmd/scale/main.go Normal file
View File

@@ -0,0 +1,20 @@
package main
import (
"flag"
"image"
"git.nkpl.cc/twocookedfaggots/imageutils"
"git.nkpl.cc/twocookedfaggots/imageutils/util"
)
var scale = flag.Int("n", 2, "rescale by factor")
func main() {
flag.Parse()
if err := util.ProcessStdio(func(img image.Image) image.Image {
return imageutils.Scale(img, *scale)
}); err != nil {
panic(err)
}
}

18
pkg/center/main.go Normal file
View File

@@ -0,0 +1,18 @@
package center
type Into struct {
Src, Dst image.Image
}
func (i Into) Bounds() image.Rectangle { return i.Dst.Bounds() }
func (i Into) ColorModel() color.Model { return i.Dst.ColorModel }
func (i Into) At(x, y int) color.Color {
x1, y1 := (i.Dst.Bounds().Dx()/2)-(i.Src.Bounds().Dx()/2),
(i.Dst.Bounds().Dy()/2)-(i.Src.Bounds().Dy()/2)
r := image.Rect(x1, y1,
x1+i.Src.Bounds().Dx(), y1+i.Src.Bounds().Dy())
if (image.Point{x, y}).In(r) {
return i.Src.At(x-x1,y-y2)
}
return i.Dst.At(x, y)
}

8
pkg/clock/README.md Normal file
View File

@@ -0,0 +1,8 @@
залил как есть.
любая кринжовая хуйня которая здесь найдется... просто зайбейте на это хуй, не обращайте внимания
запускается значится так:
заходите в cmd и...
> go run .
заходите в бровз и пишите адрес с портом

82
pkg/clock/clock.go Normal file
View File

@@ -0,0 +1,82 @@
//go:build draft
package clock
import (
"image"
"image/color"
"image/png"
"io"
"strconv"
"time"
"git.niplace.ru/XoxJlopeZi4BB/clock/letter"
"git.niplace.ru/XoxJlopeZi4BB/imageutils"
)
var img1, img2 = letter.Render(letter.Nums[6]), letter.Render(letter.Nums[9])
func DownRightBlank(img image.Image) image.Image {
clr := color.White
img = letter.Blank(img, clr, imageutils.Down)
return letter.Blank(img, clr, imageutils.Right)
}
func LeftUpBlank(img image.Image) image.Image {
clr := color.White
img = letter.Blank(img, clr, imageutils.Left)
return letter.Blank(img, clr, imageutils.Up)
}
func RenderNum(n int) image.Image {
var img image.Image = image.NewRGBA(image.Rect(0, 0, 0, 0))
s := strconv.Itoa(n)
for i := range s {
n, err := strconv.Atoi(string(s[i]))
if err != nil {
panic(err)
}
num := letter.Render(letter.Nums[n])
num = DownRightBlank(num)
img = imageutils.Concat(img, num, imageutils.Right)
}
img = LeftUpBlank(img)
return img
}
func RenderTime(t time.Time) image.Image {
hour := RenderNum(t.Hour())
if t.Hour() < 10 {
hour = imageutils.Concat(
DownRightBlank(letter.Empty), hour, imageutils.Right)
}
minute := RenderNum(t.Minute())
if t.Minute() < 10 {
minute = imageutils.Concat(
DownRightBlank(letter.Empty), minute, imageutils.Right)
}
img := imageutils.Concat(hour, minute, imageutils.Down)
return img
}
func Margin(img image.Image, length int) image.Image {
for i := 0; i < length; i++ {
img = LeftUpBlank(DownRightBlank(img))
}
return img
}
func Time(w io.Writer) {
t := time.Now()
img := RenderTime(t)
img = Margin(img, 3)
img = imageutils.Scale(img, 1<<6)
err := png.Encode(w, img)
if err != nil {
panic(err)
}
}

13
pkg/clock/clock_test.go Normal file
View File

@@ -0,0 +1,13 @@
//go:build ignore
package clock
import (
"io"
"testing"
)
func BenchmarkNumber(b *testing.B) {
for i := 0; i < b.N; i++ {
Numbers(io.Discard)
}
}

22
pkg/clock/cmd/main.go Normal file
View File

@@ -0,0 +1,22 @@
package main
import (
"net/http"
"git.niplace.ru/XoxJlopeZi4BB/clock"
)
func main() {
addrwithport := ":8080"
http.HandleFunc("/",
func(w http.ResponseWriter, req *http.Request) {
clock.Time(w)
},
)
println("this thingy running on", addrwithport)
err := http.ListenAndServe(addrwithport, nil)
if err != nil {
panic(err)
}
}

22
pkg/clock/digit/digit.go Normal file
View File

@@ -0,0 +1,22 @@
package main
import (
"fmt"
"time"
)
func main() {
d, err := time.ParseDuration("1s")
if err != nil {
panic(err)
}
t := time.Tick(d)
go func() {
fmt.Printf("\033[2J\033[H")
for {
<-t
fmt.Printf("\r%s", time.Now().Format(time.TimeOnly))
}
}()
select {}
}

5
pkg/clock/go.mod Normal file
View File

@@ -0,0 +1,5 @@
module git.niplace.ru/XoxJlopeZi4BB/clock
go 1.25.3
require git.niplace.ru/XoxJlopeZi4BB/imageutils v0.0.0-20241224134015-2709034fc322

4
pkg/clock/go.sum Normal file
View File

@@ -0,0 +1,4 @@
git.niplace.ru/XoxJlopeZi4BB/imageutils v0.0.0-20241224134015-2709034fc322 h1:jefEdqKZ/JKnmky9LipaS/UH0phAhz/56ORHIjmHREk=
git.niplace.ru/XoxJlopeZi4BB/imageutils v0.0.0-20241224134015-2709034fc322/go.mod h1:QieEgSGk9ZYISDv5XyMMktQXi/2qlTmdHuxTlt1Xfq8=
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=

106
pkg/clock/letter/image.go Normal file
View File

@@ -0,0 +1,106 @@
package letter
import (
"embed"
"encoding/csv"
"image"
"image/color"
"image/draw"
"io"
"git.niplace.ru/XoxJlopeZi4BB/imageutils"
)
type Letter string
//go:embed map.csv
var fs embed.FS
var mapFile = func() io.Reader {
f, err := fs.Open("map.csv")
if err != nil {
panic(err)
}
return f
}()
var Letters = func(r io.Reader) (m map[string]string) {
records, err := csv.NewReader(r).ReadAll()
if err != nil {
panic(err)
}
for _, v := range records {
if len(v) < 2 {
panic("csv file isn's key-value pair")
}
m[v[0]] = v[1]
}
return m
}(mapFile)
// implements image.Image interface.
func (l Letter) ColorModel() color.Model {
return color.Alpha16Model
}
// implements image.Image interface.
func (l Letter) Bounds() image.Rectangle {
return image.Rect(0, 0, 3, 3)
}
// implements image.Image interface.
func (l Letter) At(x, y int) color.Color {
if len(l) != 9 {
panic("len(Letter) != 9")
}
target := l[x+y*3]
if target != '1' {
return color.Opaque
}
return color.Transparent
}
func Render(l Letter) image.Image {
img := image.NewRGBA(l.Bounds())
draw.Draw(img, l.Bounds(), image.White, image.ZP, draw.Src)
draw.Draw(img, l.Bounds(), l, image.ZP, draw.Over)
return img
}
type blank struct {
image.Image
color.Color
imageutils.Side
}
func (b blank) ColorModel() color.Model { return b.Image.ColorModel() }
func (b blank) Bounds() image.Rectangle {
rect := image.Rectangle{}
switch b.Side {
case imageutils.Left:
fallthrough
case imageutils.Right:
rect = image.Rectangle{
image.ZP,
image.Point{
1, b.Image.Bounds().Dy(),
},
}
case imageutils.Up:
fallthrough
case imageutils.Down:
rect = image.Rectangle{
image.ZP,
image.Point{
b.Image.Bounds().Dx(), 1,
},
}
}
return rect
}
func (b blank) At(x, y int) color.Color { return b.Color }
func Blank(img image.Image, clr color.Color, side imageutils.Side) image.Image {
return imageutils.Concat(img, blank{img, clr, side}, side)
}

11
pkg/clock/letter/map.csv Normal file
View File

@@ -0,0 +1,11 @@
0, 111101111
1, 010010010
2, 110010011
3, 111011111
4, 101111001
5, 011010110
6, 001111111
7, 111001001
8, 011111111
9, 111111001
:, 010000010
1 0 111101111
2 1 010010010
3 2 110010011
4 3 111011111
5 4 101111001
6 5 011010110
7 6 001111111
8 7 111001001
9 8 011111111
10 9 111111001
11 : 010000010

35
pkg/clock/string.go Normal file
View File

@@ -0,0 +1,35 @@
package clock
import (
"git.nkpl.cc/twocookedfaggots/imageutils/clock/letter"
)
var blank = Letter("000000000")
type String struct {
S string
}
func (s String) Bounds() image.Rectangle {
splitted := strings.Split(s.S, '\n')
max := 0
for _, v := range splitted {
max = max(len(v), max)
}
x, y := max*4+1, len(splitted)*4+1
return image.Rect(0,0,x,y)
}
func (s String) ColorModel() color.Model { return color.Alpha16Model }
func (s String) At(x, y int) color.Color {
splitted := string.Split(s.S, '\n')
if y/4 > len(splitted) {
return blank.At(0, 0)
}
if x/4 > len(splitted[y/4]) {
return blank.At(0, 0)
}
c := splitted[y/4][x/4]
return Letter(c).At(x%4, y%4)
}

View File

@@ -9,6 +9,7 @@ const side = 16
type grid struct {
color.Gray
Factor float64
}
func (_ grid) ColorModel() color.Model {
@@ -20,7 +21,7 @@ func (_ grid) Bounds() image.Rectangle {
}
func (g grid) At(x, y int) color.Color {
n := uint8(g.Gray.Y * 10)
n := uint8(float64(g.Gray.Y) * g.Factor)
if n == 0 {
return color.Black
@@ -52,12 +53,13 @@ func (g uniformGrid) At(x, y int) color.Color {
type Dithering struct {
image.Image
Factor float64
}
func (d Dithering) ColorModel() color.Model { return color.GrayModel }
func (d Dithering) Bounds() image.Rectangle { return d.Image.Bounds() }
func (d Dithering) At(x, y int) color.Color {
c := color.GrayModel.Convert(d.Image.At(x, y))
return uniformGrid{grid{c.(color.Gray)}}.
return uniformGrid{grid{c.(color.Gray), d.Factor}}.
At(x, y)
}

View File

@@ -13,6 +13,8 @@ import (
"golang.org/x/image/font"
"golang.org/x/image/font/gofont/gomono"
"golang.org/x/image/math/fixed"
"git.nkpl.cc/twocookedfaggots/imageutils/pkg/mesh/wallpaper"
// "github.com/droyo/styx"
// "io/fs"
)
@@ -42,22 +44,22 @@ func render(img image.Image) draw.Image {
}
func main() {
// x := flag.Int("x", 2, "use to grid by x axis")
// y := flag.Int("y", 2, "use to grid by y axis")
// 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,
// },
// Mesh{ // our image modifyer
// Image: img,
// X: *x,
// Y: *y,
// },
dst := render(
img,
img,
)
f, err := truetype.Parse(gomono.TTF)
@@ -75,16 +77,16 @@ func main() {
Src: image.NewUniform(color.Black),
Face: face,
Dot: fixed.Point26_6{fixed.Int26_6(img.Bounds().Dx() /
9*64,
9 * 64,
),
fixed.Int26_6(img.Bounds().Dy() /
5*64,
5 * 64,
),
},
}
d.DrawString(time.Now().Format(time.Kitchen))
err = png.Encode(os.Stdout, dst)
err = wallpaper.Wallpaper(dst)
if err != nil {
panic(err)
}

23
pkg/mesh/test_cmd.go Normal file
View File

@@ -0,0 +1,23 @@
package main
import (
"os"
"os/exec"
)
func main() {
f, err := os.Open("/home/potassium/documents/wallpaper/8.png")
if err != nil {
panic(err)
}
cmd := exec.Command(
"swaybg",
"--image", "/dev/stdin",
)
cmd.Stderr = os.Stderr
cmd.Stdin = f
err = cmd.Run()
if err != nil {
panic(err)
}
}

View File

@@ -0,0 +1,37 @@
package wallpaper
import (
"bytes"
"image"
"image/png"
"os"
"os/exec"
)
var err error
func Wallpaper(img image.Image) error {
/*
cmd := exec.Command(
"swaybg",
"--image", "/dev/stdin",
"--mode", "fill",
)
*/
cmd := exec.Command("imv", "/dev/stdin")
var buf = new(bytes.Buffer)
err := png.Encode(buf, img)
if err != nil {
panic(err)
}
cmd.Stderr = os.Stdout
cmd.Stdin = buf
err = cmd.Run()
if err != nil {
return err
}
return nil
}

View File

@@ -5,6 +5,8 @@ import (
"image/color"
"image/png"
"os"
"git.nkpl.cc/twocookedfaggots/imageutils/util"
)
func NegateRGBA(c color.RGBA) color.RGBA {
@@ -30,15 +32,10 @@ func (n Negate) At(x, y int) color.Color {
return NegateRGBA(RGBAColor)
}
func check(err error) {
if err != nil {
func main() {
if err := util.ProcessStdio(func(img image.Image) image.Image {
return Negate{img}
}); err != nil {
panic(err)
}
}
func main() {
img, err := png.Decode(os.Stdin)
check(err)
err = png.Encode(os.Stdout, Negate{img})
check(err)
}

View File

@@ -38,7 +38,7 @@ func (r rescaled) At(x, y int) color.Color {
// Scale scales image.Image to a given scale
// and then returns image.Image.
// For now it will work only with positive integers.
func Scale(scale int, img image.Image) image.Image {
func Scale(img image.Image, scale int) image.Image {
if scale < 1 {
scale = 1
}