[Rendering of binary files]
Ways to render: - Hilbert Curve - Snake
This commit is contained in:
commit
f710ed8451
12 changed files with 548 additions and 0 deletions
186
generate.go
Normal file
186
generate.go
Normal file
|
@ -0,0 +1,186 @@
|
|||
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 x := startX; x < stopX; x++ {
|
||||
for y := startY; y < stopY; y++ {
|
||||
|
||||
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
|
||||
}
|
25
go.mod
Normal file
25
go.mod
Normal file
|
@ -0,0 +1,25 @@
|
|||
module git.ctdo.de/xoy/binaryimage
|
||||
|
||||
go 1.23.4
|
||||
|
||||
require (
|
||||
github.com/gofiber/fiber/v2 v2.52.6
|
||||
github.com/gofiber/template/html/v2 v2.1.3
|
||||
golang.org/x/image v0.24.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/gofiber/template v1.8.3 // indirect
|
||||
github.com/gofiber/utils v1.1.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.51.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
)
|
43
go.sum
Normal file
43
go.sum
Normal file
|
@ -0,0 +1,43 @@
|
|||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI=
|
||||
github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
||||
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
|
||||
github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
|
||||
github.com/gofiber/template/html/v2 v2.1.3 h1:n1LYBtmr9C0V/k/3qBblXyMxV5B0o/gpb6dFLp8ea+o=
|
||||
github.com/gofiber/template/html/v2 v2.1.3/go.mod h1:U5Fxgc5KpyujU9OqKzy6Kn6Qup6Tm7zdsISR+VpnHRE=
|
||||
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
|
||||
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
|
||||
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=
|
||||
golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
54
hilbertcurve.go
Normal file
54
hilbertcurve.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
package main
|
||||
|
||||
type HilbertCurve struct {
|
||||
order int
|
||||
curve *Matrix
|
||||
}
|
||||
|
||||
func NewHilbertCurve() *HilbertCurve {
|
||||
h := &HilbertCurve{
|
||||
curve: NewMatrix(2, 2),
|
||||
}
|
||||
|
||||
h.curve.Set(0, 0, 1)
|
||||
h.curve.Set(0, 1, 0)
|
||||
h.curve.Set(1, 0, 2)
|
||||
h.curve.Set(1, 1, 3)
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func (h *HilbertCurve) ToString() string {
|
||||
return h.curve.ToString()
|
||||
}
|
||||
|
||||
func (h *HilbertCurve) Length() int {
|
||||
return h.curve.width * h.curve.height
|
||||
}
|
||||
|
||||
func (h *HilbertCurve) Expand() {
|
||||
length := h.Length()
|
||||
|
||||
m3 := h.curve.Transpose()
|
||||
|
||||
m0 := m3.Mirror()
|
||||
m3.Add(3 * length)
|
||||
|
||||
h.curve.Add(length)
|
||||
|
||||
m2 := h.curve.Clone()
|
||||
m2.Add(length)
|
||||
|
||||
bottom := m0.MergeRight(m3)
|
||||
|
||||
h.curve = h.curve.MergeRight(m2).MergeBottom(bottom)
|
||||
h.order++
|
||||
}
|
||||
|
||||
func (h *HilbertCurve) Order() int {
|
||||
return h.order
|
||||
}
|
||||
|
||||
func (h *HilbertCurve) Get() *Matrix {
|
||||
return h.curve
|
||||
}
|
54
main.go
Normal file
54
main.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/template/html/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
engine := html.New("views", ".html")
|
||||
|
||||
app := fiber.New(fiber.Config{
|
||||
Views: engine,
|
||||
BodyLimit: 10 * 1024 * 1024 * 1024, // 1GiB
|
||||
})
|
||||
|
||||
app.Static("/", "static")
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.Render("index", fiber.Map{
|
||||
"Stylenames": []string{"colors", "main", "index"},
|
||||
})
|
||||
})
|
||||
|
||||
app.Post("/generate", func(c *fiber.Ctx) error {
|
||||
c.Accepts("multipart/form-data")
|
||||
file, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
openedFile, err := file.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data, err := io.ReadAll(openedFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
img, err := HilbertCurveGenerateByteImage(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Type("bmp")
|
||||
c.Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", file.Filename+".bmp"))
|
||||
return c.Send(img)
|
||||
})
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
154
matrix.go
Normal file
154
matrix.go
Normal file
|
@ -0,0 +1,154 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Matrix struct {
|
||||
width int
|
||||
height int
|
||||
matrix [][]int
|
||||
}
|
||||
|
||||
func NewMatrix(width, height int) *Matrix {
|
||||
m := &Matrix{
|
||||
width: width,
|
||||
height: height,
|
||||
matrix: make([][]int, height),
|
||||
}
|
||||
|
||||
for i := 0; i < height; i++ {
|
||||
m.matrix[i] = make([]int, width)
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *Matrix) Size() (int, int) {
|
||||
return m.width, m.height
|
||||
}
|
||||
|
||||
func (m *Matrix) At(x, y int) int {
|
||||
return m.matrix[y][x]
|
||||
}
|
||||
|
||||
func (m *Matrix) Set(x, y, value int) {
|
||||
m.matrix[y][x] = value
|
||||
}
|
||||
|
||||
func (m *Matrix) Get() [][]int {
|
||||
return m.matrix
|
||||
}
|
||||
|
||||
func (m *Matrix) Transpose() *Matrix {
|
||||
M := NewMatrix(m.height, m.width)
|
||||
for x := 0; x < m.width; x++ {
|
||||
for y := 0; y < m.height; y++ {
|
||||
M.Set(y, x, m.At(x, y))
|
||||
}
|
||||
}
|
||||
return M
|
||||
}
|
||||
|
||||
func (m *Matrix) MirrorX() *Matrix {
|
||||
M := NewMatrix(m.width, m.height)
|
||||
for x := 0; x < m.width; x++ {
|
||||
for y := 0; y < m.height; y++ {
|
||||
M.Set(x, y, m.At((m.width-1)-x, y))
|
||||
}
|
||||
}
|
||||
return M
|
||||
}
|
||||
|
||||
func (m *Matrix) MirrorY() *Matrix {
|
||||
M := NewMatrix(m.width, m.height)
|
||||
for x := 0; x < m.width; x++ {
|
||||
for y := 0; y < m.height; y++ {
|
||||
M.Set(x, y, m.At(x, (m.height-1)-y))
|
||||
}
|
||||
}
|
||||
return M
|
||||
}
|
||||
|
||||
func (m *Matrix) Mirror() *Matrix {
|
||||
M := NewMatrix(m.width, m.height)
|
||||
for x := 0; x < m.width; x++ {
|
||||
for y := 0; y < m.height; y++ {
|
||||
M.Set(x, y, m.At((m.width-1)-x, (m.height-1)-y))
|
||||
}
|
||||
}
|
||||
return M
|
||||
}
|
||||
|
||||
func (m *Matrix) Add(value int) {
|
||||
for x := 0; x < m.width; x++ {
|
||||
for y := 0; y < m.height; y++ {
|
||||
m.matrix[y][x] += value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Matrix) MergeRight(M *Matrix) *Matrix {
|
||||
var maxHeight int
|
||||
|
||||
if m.height > M.height {
|
||||
maxHeight = m.height
|
||||
} else {
|
||||
maxHeight = M.height
|
||||
}
|
||||
|
||||
mM := NewMatrix(m.width+M.width, maxHeight)
|
||||
for y := 0; y < m.height; y++ {
|
||||
for x := 0; x < m.width; x++ {
|
||||
mM.Set(x, y, m.At(x, y))
|
||||
}
|
||||
}
|
||||
for y := 0; y < M.height; y++ {
|
||||
for x := 0; x < M.width; x++ {
|
||||
mM.Set(m.width+x, y, M.At(x, y))
|
||||
}
|
||||
}
|
||||
return mM
|
||||
}
|
||||
|
||||
func (m *Matrix) MergeBottom(M *Matrix) *Matrix {
|
||||
var maxWidth int
|
||||
|
||||
if m.width > M.width {
|
||||
maxWidth = m.width
|
||||
} else {
|
||||
maxWidth = M.width
|
||||
}
|
||||
|
||||
mM := NewMatrix(maxWidth, m.height+M.height)
|
||||
for y := 0; y < m.height; y++ {
|
||||
for x := 0; x < m.width; x++ {
|
||||
mM.Set(x, y, m.At(x, y))
|
||||
}
|
||||
}
|
||||
for y := 0; y < M.height; y++ {
|
||||
for x := 0; x < M.width; x++ {
|
||||
mM.Set(x, m.height+y, M.At(x, y))
|
||||
}
|
||||
}
|
||||
return mM
|
||||
}
|
||||
|
||||
func (m *Matrix) ToString() string {
|
||||
str := ""
|
||||
for y := 0; y < m.height; y++ {
|
||||
for x := 0; x < m.width; x++ {
|
||||
str += fmt.Sprintf(" %v ", m.At(x, y))
|
||||
}
|
||||
str += "\n"
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
func (m *Matrix) Clone() *Matrix {
|
||||
M := NewMatrix(m.width, m.height)
|
||||
for y := 0; y < m.height; y++ {
|
||||
for x := 0; x < m.width; x++ {
|
||||
M.Set(x, y, m.At(x, y))
|
||||
}
|
||||
}
|
||||
return M
|
||||
}
|
0
static/css/colors.css
Normal file
0
static/css/colors.css
Normal file
0
static/css/index.css
Normal file
0
static/css/index.css
Normal file
0
static/css/main.css
Normal file
0
static/css/main.css
Normal file
9
views/index.html
Normal file
9
views/index.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
{{template "partials/base-top" .}}
|
||||
|
||||
<form action="/generate" method="post" enctype="multipart/form-data">
|
||||
<label for="file">File:</label>
|
||||
<input type="file" name="file" id="file">
|
||||
<button type="submit">Generate</button>
|
||||
</form>
|
||||
|
||||
{{template "partials/base-bottom" .}}
|
8
views/partials/base-bottom.html
Normal file
8
views/partials/base-bottom.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
</main>
|
||||
<footer>
|
||||
<nav>
|
||||
<a href="https://git.ctdo.de/xoy/binaryimage">Repository</a>
|
||||
</nav>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
15
views/partials/base-top.html
Normal file
15
views/partials/base-top.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>BinaryImage</title>
|
||||
{{ range .Stylenames }}
|
||||
<link rel="stylesheet" href="css/{{ . }}.css">
|
||||
{{ end }}
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>BinaryImage</h1>
|
||||
</header>
|
||||
<main>
|
Loading…
Add table
Reference in a new issue