Fix up some bugs and update to modern go

This commit is contained in:
Justin Hawkins 2024-05-15 18:45:29 +09:30
parent f740dc806b
commit 85dafe4120
3 changed files with 95 additions and 82 deletions

7
go.mod Normal file
View File

@ -0,0 +1,7 @@
module github.com/tardisx/slicerdicer
go 1.22.1
require github.com/disintegration/imaging v1.6.2
require golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 // indirect

5
go.sum Normal file
View File

@ -0,0 +1,5 @@
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

165
main.go
View File

@ -1,109 +1,110 @@
package main;
package main
import "image"
import "image/png"
import "github.com/disintegration/imaging"
import "runtime"
import "flag"
import "fmt"
import "os"
import (
"flag"
"fmt"
"image"
"image/png"
"os"
"github.com/disintegration/imaging"
)
const currentVersion = "0.01"
func main() {
filenamePtr := flag.String("filename", "", "filename to open")
tileSizePtr := flag.Int ("tile-size", 256, "tile size, in pixels")
concurrencyPtr := flag.Int ("concurrency", 5, "how many tiles to generate concurrently (threads)")
filenamePtr := flag.String("filename", "", "filename to open")
tileSizePtr := flag.Int("tile-size", 256, "tile size, in pixels")
concurrencyPtr := flag.Int("concurrency", 5, "how many tiles to generate concurrently (threads)")
baseName := flag.String("basename", "tile", "base of the output files")
flag.Parse()
flag.Parse()
if (*filenamePtr == "") {
fmt.Println("Error: You must specify a filename with --filename");
return;
}
if *filenamePtr == "" {
fmt.Println("Error: You must specify a filename with --filename")
return
}
fmt.Println("opening file:", *filenamePtr)
src, err := imaging.Open(*filenamePtr)
if err != nil {
fmt.Println("Error: Could not open file:", err)
return;
}
fmt.Println("opening file:", *filenamePtr)
src, err := imaging.Open(*filenamePtr)
if err != nil {
fmt.Println("Error: Could not open file:", err)
return
}
size := src.Bounds().Max
size := src.Bounds().Max
tile_size_x := *tileSizePtr
tile_size_y := *tileSizePtr
tile_size_x := *tileSizePtr
tile_size_y := *tileSizePtr
// work out maximum zoom
var max_zoom int
zoom_test_size_x := size.X
zoom_test_size_y := size.Y
for max_zoom = 0 ; ; max_zoom++ {
if zoom_test_size_x < tile_size_x && zoom_test_size_y < tile_size_y {
break
}
zoom_test_size_x = zoom_test_size_x >> 1
zoom_test_size_y = zoom_test_size_y >> 1
}
// work out maximum zoom
var max_zoom int
zoom_test_size_x := size.X
zoom_test_size_y := size.Y
for max_zoom = 0; ; max_zoom++ {
if zoom_test_size_x <= tile_size_x && zoom_test_size_y <= tile_size_y {
break
}
zoom_test_size_x = zoom_test_size_x >> 1
zoom_test_size_y = zoom_test_size_y >> 1
}
z := max_zoom
fmt.Println("maximum zoom level is", max_zoom)
z := max_zoom
fmt.Println("maximum zoom level is", max_zoom)
concurrency := *concurrencyPtr
sem := make(chan bool, concurrency)
concurrency := *concurrencyPtr
sem := make(chan bool, concurrency)
fmt.Println("starting tiling with concurrency of", concurrency)
fmt.Println("starting tiling with concurrency of", concurrency)
// outer loop for zoom
for {
if (z == max_zoom) {
// do nothing
} else {
// halve image size
src = imaging.Resize(src, size.X/2, 0, imaging.NearestNeighbor)
runtime.GC()
// recalculate size
size = src.Bounds().Max
}
// outer loop for zoom
for {
if z == max_zoom {
// do nothing
} else {
// halve image size
src = imaging.Resize(src, size.X/2, 0, imaging.NearestNeighbor)
// recalculate size
size = src.Bounds().Max
}
fmt.Print(fmt.Sprintf("zoom level: %d (%d x %d)\n", z, size.X, size.Y))
fmt.Print(fmt.Sprintf("zoom level: %d (%d x %d)\n", z, size.X, size.Y))
for y := 0 ; y <= (size.Y / tile_size_y) ; y++ {
for x := 0 ; x <= (size.X / tile_size_x) ; x++ {
sem <- true
go tile(src, z, x, y, tile_size_x, tile_size_y, sem)
}
for y := 0; y < (size.Y / tile_size_y); y++ {
for x := 0; x < (size.X / tile_size_x); x++ {
sem <- true
go tile(*baseName, src, z, x, y, tile_size_x, tile_size_y, sem)
}
}
}
z--
if (z < 0) {
break
}
}
z--
if z < 0 {
break
}
}
// drain at the end of each zoom level
// since we are about to modify the source image
for i := 0; i < cap(sem); i++ {
sem <- true
}
// drain at the end of each zoom level
// since we are about to modify the source image in memory
for i := 0; i < cap(sem); i++ {
sem <- true
}
fmt.Println("done")
fmt.Println("done")
}
func tile (src image.Image, z, x, y int, tile_size_x, tile_size_y int, sem chan bool) {
defer func() { <-sem }()
output_filename := fmt.Sprintf("tile-%d-%d-%d.png", z, x, y)
cropped := imaging.Crop(src, image.Rect(tile_size_x*x, tile_size_y*y, tile_size_x*x+tile_size_x, tile_size_y*y+tile_size_y));
func tile(basename string, src image.Image, z, x, y int, tile_size_x, tile_size_y int, sem chan bool) {
defer func() { <-sem }()
output_filename := fmt.Sprintf("%s-%d-%d-%d.png", basename, z, x, y)
cropped := imaging.Crop(src, image.Rect(tile_size_x*x, tile_size_y*y, tile_size_x*x+tile_size_x, tile_size_y*y+tile_size_y))
writer, _ := os.Create(output_filename)
err := png.Encode(writer, cropped)
if err != nil {
fmt.Println(err)
}
writer.Close()
writer, _ := os.Create(output_filename)
err := png.Encode(writer, cropped)
if err != nil {
fmt.Println(err)
}
writer.Close()
runtime.GC()
return;
return
}