Add concurrency.
This commit is contained in:
parent
4cc498adab
commit
e2ee7ae4aa
10
README.md
10
README.md
@ -21,4 +21,12 @@ the top left tile.
|
|||||||
|
|
||||||
slicerdicer --help
|
slicerdicer --help
|
||||||
|
|
||||||
slicerdicer --filename foo.png --tile-size 256
|
slicerdicer --filename foo.png --tile-size 256 --concurrency 5
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
It's going to eat some memory.
|
||||||
|
|
||||||
|
In my tests on an 32641 x 16471, 8-bit/color RGB PNG, memory usage peaks at
|
||||||
|
around 2.7GB.
|
||||||
|
|
||||||
|
65
main.go
65
main.go
@ -5,15 +5,14 @@ import "image/png"
|
|||||||
import "github.com/disintegration/imaging"
|
import "github.com/disintegration/imaging"
|
||||||
import "runtime"
|
import "runtime"
|
||||||
import "flag"
|
import "flag"
|
||||||
|
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
import "os"
|
import "os"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
filenamePtr := flag.String("filename", "screenshot.png", "filename to open")
|
filenamePtr := flag.String("filename", "screenshot.png", "filename to open")
|
||||||
tile_size := flag.Int ("tile-size", 512, "tile size, in pixels")
|
tileSizePtr := flag.Int ("tile-size", 512, "tile size, in pixels")
|
||||||
|
concurrencyPtr := flag.Int ("concurrency", 5, "how many tiles to generate concurrently (threads)")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
@ -26,20 +25,24 @@ func main() {
|
|||||||
|
|
||||||
size := src.Bounds().Max
|
size := src.Bounds().Max
|
||||||
|
|
||||||
tile_size_x := *tile_size
|
tile_size_x := *tileSizePtr
|
||||||
tile_size_y := *tile_size
|
tile_size_y := *tileSizePtr
|
||||||
|
|
||||||
fmt.Println("starting tiling")
|
|
||||||
|
|
||||||
z := 0
|
z := 0
|
||||||
|
|
||||||
|
concurrency := *concurrencyPtr
|
||||||
|
sem := make(chan bool, concurrency)
|
||||||
|
|
||||||
|
fmt.Println("starting tiling with concurrency of", concurrency)
|
||||||
|
|
||||||
// outer loop for zoom
|
// outer loop for zoom
|
||||||
for {
|
for {
|
||||||
if (z == 0) {
|
if (z == 0) {
|
||||||
// do nothing
|
// do nothing
|
||||||
} else {
|
} else {
|
||||||
// halve image size
|
// halve image size
|
||||||
src = imaging.Resize(src, size.X/2, 0, imaging.Linear)
|
src = imaging.Resize(src, size.X/2, 0, imaging.NearestNeighbor)
|
||||||
|
runtime.GC()
|
||||||
// recalculate size
|
// recalculate size
|
||||||
size = src.Bounds().Max
|
size = src.Bounds().Max
|
||||||
// we are done if we are now smaller then the tile
|
// we are done if we are now smaller then the tile
|
||||||
@ -51,29 +54,37 @@ func main() {
|
|||||||
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 y := 0 ; y <= (size.Y / tile_size_y) ; y++ {
|
||||||
|
|
||||||
for x := 0 ; x <= (size.X / tile_size_x) ; x++ {
|
for x := 0 ; x <= (size.X / tile_size_x) ; x++ {
|
||||||
|
sem <- true
|
||||||
output_filename := fmt.Sprintf("tile-%d-%d-%d.png", z, x, y)
|
go tile(src, z, x, y, tile_size_x, tile_size_y, sem)
|
||||||
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));
|
}
|
||||||
|
|
||||||
fmt.Print("writing to: ", output_filename, " ");
|
|
||||||
fmt.Print("\r")
|
|
||||||
|
|
||||||
writer, _ := os.Create(output_filename)
|
|
||||||
err = png.Encode(writer, cropped)
|
|
||||||
writer.Close()
|
|
||||||
runtime.GC()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Print("\r \r")
|
|
||||||
z++
|
z++
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("done")
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
writer, _ := os.Create(output_filename)
|
||||||
|
err := png.Encode(writer, cropped)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
writer.Close()
|
||||||
|
|
||||||
|
runtime.GC()
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user