binaryimage/generate.go
2025-02-28 23:34:15 +01:00

186 lines
3.2 KiB
Go

package main
import (
"bytes"
"fmt"
"image"
"image/color"
"math"
"sync"
"time"
"golang.org/x/image/bmp"
)
func SnakeGenerateByteImagePart(data []byte, startX, startY, stopX, stopY, xLen, yLen int, img *image.RGBA) {
for y := startY; y < stopY; y++ {
for x := startX; x < stopX; x++ {
B := byte(0)
if x+y*xLen < len(data) {
B = data[x+y*xLen]
}
r, g, b := byte(0), byte(0), byte(0)
if B > 0 {
r = B >> 6
g = (B >> 4) & 3
b = (B >> 2) & 3
a := B & 3
r = (r << 2) + a
g = (g << 2) + a
b = (b << 2) + a
r <<= 4
g <<= 4
b <<= 4
}
img.Set(x, y, color.RGBA{r, g, b, 0xFF})
}
}
}
func SnakeGenerateByteImage(data []byte) ([]byte, error) {
length := len(data)
xLen := int(math.Floor(math.Sqrt(float64(length))))
yLen := xLen
if yLen*xLen < int(length) {
yLen++
}
img := image.NewRGBA(image.Rect(0, 0, xLen-1, yLen-1))
fmt.Printf("Start generating image of data with %d bytes\n", length)
startTime := time.Now()
var wg sync.WaitGroup
wg.Add(4)
go func() {
SnakeGenerateByteImagePart(data, 0, 0, xLen/2, yLen/2, xLen, yLen, img)
wg.Done()
}()
go func() {
SnakeGenerateByteImagePart(data, xLen/2, 0, xLen, yLen/2, xLen, yLen, img)
wg.Done()
}()
go func() {
SnakeGenerateByteImagePart(data, 0, yLen/2, xLen/2, yLen, xLen, yLen, img)
wg.Done()
}()
go func() {
SnakeGenerateByteImagePart(data, xLen/2, yLen/2, xLen, yLen, xLen, yLen, img)
wg.Done()
}()
wg.Wait()
endTime := time.Now()
fmt.Printf("Generated in %f seconds\n", endTime.Sub(startTime).Seconds())
fmt.Println("Start encoding image as bmp")
startTime = time.Now()
buffer := new(bytes.Buffer)
err := bmp.Encode(buffer, img)
if err != nil {
return nil, err
}
endTime = time.Now()
fmt.Printf("Encoded in %f seconds\n", endTime.Sub(startTime).Seconds())
return buffer.Bytes(), nil
}
func HilbertCurveGenerateByteImage(data []byte) ([]byte, error) {
length := len(data)
fmt.Printf("Start generating hilbert curve")
startTime := time.Now()
h := NewHilbertCurve()
for length > h.Length() {
h.Expand()
}
endTime := time.Now()
fmt.Printf("Generated a hilbert curve of order %d in %f seconds", h.Order(), endTime.Sub(startTime).Seconds())
fmt.Printf("Start generating image of data with %d bytes\n", length)
startTime = time.Now()
curve := h.Get()
img := image.NewRGBA(image.Rect(0, 0, curve.width-1, curve.height-1))
for y := 0; y < curve.height; y++ {
for x := 0; x < curve.width; x++ {
B := byte(0)
pos := curve.At(x, y)
if pos < len(data) {
B = data[pos]
}
r, g, b := byte(0), byte(0), byte(0)
if B > 0 {
r = B >> 6
g = (B >> 4) & 3
b = (B >> 2) & 3
a := B & 3
r = (r << 2) + a
g = (g << 2) + a
b = (b << 2) + a
r <<= 4
g <<= 4
b <<= 4
}
img.Set(x, y, color.RGBA{r, g, b, 0xFF})
}
}
endTime = time.Now()
fmt.Printf("Generated in %f seconds\n", endTime.Sub(startTime).Seconds())
fmt.Println("Start encoding image as bmp")
startTime = time.Now()
buffer := new(bytes.Buffer)
err := bmp.Encode(buffer, img)
if err != nil {
return nil, err
}
endTime = time.Now()
fmt.Printf("Encoded in %f seconds\n", endTime.Sub(startTime).Seconds())
return buffer.Bytes(), nil
}