mirror of
https://github.com/Dadido3/noita-mapcap.git
synced 2024-12-22 02:17:33 +00:00
Remove pre-render mode from stitcher & Cleanup
This commit is contained in:
parent
cd1428706e
commit
7d250d6405
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -14,9 +14,11 @@
|
||||
"gridify",
|
||||
"hacky",
|
||||
"hilbertify",
|
||||
"Hitbox",
|
||||
"ipairs",
|
||||
"kbinani",
|
||||
"Lanczos",
|
||||
"lann",
|
||||
"ldflags",
|
||||
"linearize",
|
||||
"lowram",
|
||||
@ -25,7 +27,6 @@
|
||||
"nfnt",
|
||||
"noita",
|
||||
"polymorphed",
|
||||
"prerender",
|
||||
"promptui",
|
||||
"rasterizer",
|
||||
"savegames",
|
||||
|
@ -46,8 +46,6 @@ example list of files:
|
||||
Lower bound of the output rectangle. This coordinate is not included in the output.
|
||||
- `ymin int`
|
||||
Upper bound of the output rectangle. This coordinate is included in the output.
|
||||
- `prerender`
|
||||
Pre renders the image in RAM before saving. Can speed things up if you have enough RAM.
|
||||
- `cleanup float`
|
||||
Enables cleanup mode with the given float as threshold. This will **DELETE** images from the input folder; no stitching will be done in this mode. A good value to start with is `0.999`, which deletes images where the sum of the min-max difference of each sub-pixel overlapping with other images is less than 99.9%% of the maximum possible sum of pixel differences.
|
||||
|
||||
|
@ -8,14 +8,13 @@ package main
|
||||
import (
|
||||
"encoding/json"
|
||||
"image/color"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/tdewolff/canvas"
|
||||
)
|
||||
|
||||
var entityDisplayFontFamily = canvas.NewFontFamily("times")
|
||||
var entityDisplayFontFace *canvas.FontFace
|
||||
//var entityDisplayFontFamily = canvas.NewFontFamily("times")
|
||||
//var entityDisplayFontFace *canvas.FontFace
|
||||
|
||||
var entityDisplayAreaDamageStyle = canvas.Style{
|
||||
FillColor: color.RGBA{100, 0, 0, 100},
|
||||
@ -73,13 +72,13 @@ var entityDisplayCollisionTriggerStyle = canvas.Style{
|
||||
}
|
||||
|
||||
func init() {
|
||||
fontName := "NimbusRoman-Regular"
|
||||
//fontName := "NimbusRoman-Regular"
|
||||
|
||||
if err := entityDisplayFontFamily.LoadLocalFont(fontName, canvas.FontRegular); err != nil {
|
||||
log.Printf("Couldn't load font %q: %v", fontName, err)
|
||||
}
|
||||
//if err := entityDisplayFontFamily.LoadLocalFont(fontName, canvas.FontRegular); err != nil {
|
||||
// log.Printf("Couldn't load font %q: %v", fontName, err)
|
||||
//}
|
||||
|
||||
entityDisplayFontFace = entityDisplayFontFamily.Face(48.0, canvas.White, canvas.FontRegular, canvas.FontNormal)
|
||||
//entityDisplayFontFace = entityDisplayFontFamily.Face(48.0, canvas.White, canvas.FontRegular, canvas.FontNormal)
|
||||
}
|
||||
|
||||
type Entity struct {
|
||||
@ -146,6 +145,7 @@ func (e Entity) Draw(c *canvas.Context) {
|
||||
if member, ok := component.Members["circle_radius"]; ok {
|
||||
if radius, ok := member.(float64); ok && radius > 0 {
|
||||
// Theoretically we need to clip the damage area to the intersection of the AABB and the circle, but meh.
|
||||
// TODO: Clip the area to the intersection of the box and the circle
|
||||
cx, cy := (aabbMinX+aabbMaxX)/2, (aabbMinY+aabbMaxY)/2
|
||||
c.Style = entityDisplayAreaDamageStyle
|
||||
c.DrawPath(x+cx, y+cy, canvas.Circle(radius))
|
||||
@ -201,7 +201,7 @@ func (e Entity) Draw(c *canvas.Context) {
|
||||
c.DrawPath(x+aabbMinX, y+aabbMinY, canvas.Rectangle(aabbMaxX-aabbMinX, aabbMaxY-aabbMinY))
|
||||
}
|
||||
|
||||
case "CollisionTriggerComponent": // Checks if another entity is inside the box with the given width and height.
|
||||
case "CollisionTriggerComponent": // Checks if another entity is inside the given radius and box with the given width and height.
|
||||
var width, height float64
|
||||
path := &canvas.Path{}
|
||||
if member, ok := component.Members["width"]; ok {
|
||||
@ -213,6 +213,8 @@ func (e Entity) Draw(c *canvas.Context) {
|
||||
if width > 0 && height > 0 {
|
||||
path = canvas.Rectangle(width, height).Translate(-width/2, -height/2)
|
||||
}
|
||||
// Theoretically we need to clip the area to the intersection of the box and the circle, but meh.
|
||||
// TODO: Clip the area to the intersection of the box and the circle
|
||||
//if member, ok := component.Members["radius"]; ok {
|
||||
// if radius, ok := member.(float64); ok && radius > 0 {
|
||||
// path = path.Append(canvas.Circle(radius))
|
||||
|
@ -76,7 +76,7 @@ func (mbi *MedianBlendedImage) At(x, y int) color.Color {
|
||||
|
||||
// Opaque returns whether the image is fully opaque.
|
||||
//
|
||||
// For more speed and smaller filesizes, MedianBlendedImage will be marked as non-transparent.
|
||||
// For more speed and smaller file size, MedianBlendedImage will be marked as non-transparent.
|
||||
// This will speed up image saving by 2x, as there is no need to iterate over the whole image to find a single non opaque pixel.
|
||||
func (mbi *MedianBlendedImage) Opaque() bool {
|
||||
return true
|
||||
|
@ -21,15 +21,14 @@ import (
|
||||
)
|
||||
|
||||
var flagInputPath = flag.String("input", filepath.Join(".", "..", "..", "output"), "The source path of the image tiles to be stitched.")
|
||||
var flagEntitiesInputPath = flag.String("entities", filepath.Join(".", "..", "..", "output", "entities.json"), "The source path of the entities.json file.")
|
||||
var flagPlayerPathInputPath = flag.String("player-path", filepath.Join(".", "..", "..", "output", "player-path.json"), "The source path of the player-path.json file.")
|
||||
var flagEntitiesInputPath = flag.String("entities", filepath.Join(".", "..", "..", "output", "entities.json"), "The path to the entities.json file.")
|
||||
var flagPlayerPathInputPath = flag.String("player-path", filepath.Join(".", "..", "..", "output", "player-path.json"), "The path to the player-path.json file.")
|
||||
var flagOutputPath = flag.String("output", filepath.Join(".", "output.png"), "The path and filename of the resulting stitched image.")
|
||||
var flagScaleDivider = flag.Int("divide", 1, "A downscaling factor. 2 will produce an image with half the side lengths.")
|
||||
var flagXMin = flag.Int("xmin", 0, "Left bound of the output rectangle. This coordinate is included in the output.")
|
||||
var flagYMin = flag.Int("ymin", 0, "Upper bound of the output rectangle. This coordinate is included in the output.")
|
||||
var flagXMax = flag.Int("xmax", 0, "Right bound of the output rectangle. This coordinate is not included in the output.")
|
||||
var flagYMax = flag.Int("ymax", 0, "Lower bound of the output rectangle. This coordinate is not included in the output.")
|
||||
var flagPrerender = flag.Bool("prerender", false, "Pre renders the image in RAM before saving. Can speed things up if you have enough RAM.")
|
||||
var flagCleanupThreshold = flag.Float64("cleanup", 0, "Enable cleanup mode with the given threshold. This will DELETE images from the input folder, no stitching will be done in this mode. A good value to start with is 0.999, which deletes images where the sum of the min-max difference of each sub-pixel overlapping with other images is less than 99.9%% of the maximum possible sum of pixel differences.")
|
||||
|
||||
func main() {
|
||||
@ -272,43 +271,30 @@ func main() {
|
||||
var wg sync.WaitGroup
|
||||
done := make(chan bool)
|
||||
|
||||
if *flagPrerender {
|
||||
log.Printf("Creating output image with a size of %v", outputRect.Size())
|
||||
tempImage := image.NewRGBA(outputRect)
|
||||
tempImage := NewMedianBlendedImage(tiles, outputRect)
|
||||
_, max := tempImage.Progress()
|
||||
bar.SetTotal(int64(max)).Start().SetRefreshRate(1 * time.Second)
|
||||
|
||||
log.Printf("Stitching %v tiles into an image at %v", len(tiles), tempImage.Bounds())
|
||||
if err := StitchGrid(tiles, tempImage, 512, bar); err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
bar.Finish()
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
outputImage = tempImage
|
||||
} else {
|
||||
tempImage := NewMedianBlendedImage(tiles, outputRect)
|
||||
_, max := tempImage.Progress()
|
||||
bar.SetTotal(int64(max)).Start().SetRefreshRate(1 * time.Second)
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
ticker := time.NewTicker(1 * time.Second)
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
value, _ := tempImage.Progress()
|
||||
bar.SetCurrent(int64(value))
|
||||
bar.Finish()
|
||||
return
|
||||
case <-ticker.C:
|
||||
value, _ := tempImage.Progress()
|
||||
bar.SetCurrent(int64(value))
|
||||
}
|
||||
ticker := time.NewTicker(1 * time.Second)
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
value, _ := tempImage.Progress()
|
||||
bar.SetCurrent(int64(value))
|
||||
bar.Finish()
|
||||
return
|
||||
case <-ticker.C:
|
||||
value, _ := tempImage.Progress()
|
||||
bar.SetCurrent(int64(value))
|
||||
}
|
||||
}()
|
||||
}
|
||||
}()
|
||||
|
||||
outputImage = tempImage
|
||||
}
|
||||
outputImage = tempImage
|
||||
|
||||
log.Printf("Creating output file \"%v\"", *flagOutputPath)
|
||||
f, err := os.Create(*flagOutputPath)
|
||||
@ -321,10 +307,8 @@ func main() {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
if !*flagPrerender {
|
||||
done <- true
|
||||
wg.Wait()
|
||||
}
|
||||
done <- true
|
||||
wg.Wait()
|
||||
|
||||
if err := f.Close(); err != nil {
|
||||
log.Panic(err)
|
||||
|
@ -8,15 +8,10 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"math"
|
||||
"os"
|
||||
"sort"
|
||||
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/font/basicfont"
|
||||
"golang.org/x/image/math/fixed"
|
||||
|
||||
"github.com/google/hilbert"
|
||||
)
|
||||
|
||||
@ -103,36 +98,6 @@ func hilbertifyRectangle(rect image.Rectangle, gridSize int) ([]image.Rectangle,
|
||||
return grid, nil
|
||||
}
|
||||
|
||||
func drawLabel(img *image.RGBA, x, y int, label string) {
|
||||
col := color.RGBA{200, 100, 0, 255}
|
||||
point := fixed.Point26_6{X: fixed.Int26_6(x * 64), Y: fixed.Int26_6(y * 64)}
|
||||
|
||||
d := &font.Drawer{
|
||||
Dst: img,
|
||||
Src: image.NewUniform(col),
|
||||
Face: basicfont.Face7x13,
|
||||
Dot: point,
|
||||
}
|
||||
d.DrawString(label)
|
||||
}
|
||||
|
||||
func intAbs(x int) int {
|
||||
if x < 0 {
|
||||
return -x
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
func pointAbs(p image.Point) image.Point {
|
||||
if p.X < 0 {
|
||||
p.X = -p.X
|
||||
}
|
||||
if p.Y < 0 {
|
||||
p.Y = -p.Y
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// Integer division that rounds to the next integer towards negative infinity.
|
||||
func divideFloor(a, b int) int {
|
||||
temp := a / b
|
||||
@ -154,10 +119,3 @@ func divideCeil(a, b int) int {
|
||||
|
||||
return temp
|
||||
}
|
||||
|
||||
func maxInt(x, y int) int {
|
||||
if x > y {
|
||||
return x
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user