allow saving full images

This commit is contained in:
olebeck 2022-09-09 14:58:02 +02:00
parent 833427895a
commit 4466829f75
2 changed files with 56 additions and 38 deletions

View File

@ -41,6 +41,25 @@ var MAP_ITEM_PACKET packet.InventoryContent = packet.InventoryContent{
},
}
func (m *MapUI) get_bounds() (min, max protocol.ChunkPos) {
// get the chunk coord bounds
for _ch := range m.renderedChunks {
if _ch.X() < min.X() {
min[0] = _ch.X()
}
if _ch.Z() < min.Z() {
min[1] = _ch.Z()
}
if _ch.X() > max.X() {
max[0] = _ch.X()
}
if _ch.Z() > max.Z() {
max[1] = _ch.Z()
}
}
return
}
type RenderElem struct {
pos protocol.ChunkPos
ch *chunk.Chunk
@ -149,32 +168,11 @@ func (m *MapUI) Redraw() {
}
}
// get the chunk coord bounds
min := protocol.ChunkPos{}
max := protocol.ChunkPos{}
for _ch := range m.renderedChunks {
if _ch.X() < min.X() {
min[0] = _ch.X()
}
if _ch.Z() < min.Z() {
min[1] = _ch.Z()
}
if _ch.X() > max.X() {
max[0] = _ch.X()
}
if _ch.Z() > max.Z() {
max[1] = _ch.Z()
}
}
middle := protocol.ChunkPos{
int32(m.w.PlayerPos.Position.X()),
int32(m.w.PlayerPos.Position.Z()),
}
chunks_x := int(max[0] - min[0] + 1) // how many chunk lengths is x coordinate
chunks_y := int(max[1] - min[1] + 1)
// total_width := 32 * math.Ceil(float64(chunks_x)/32)
chunks_per_line := float64(128 / m.zoomLevel)
px_per_block := 128 / chunks_per_line / 16 // how many pixels per block
@ -202,29 +200,39 @@ func (m *MapUI) Redraw() {
draw_full := false
if draw_full {
img2 := image.NewRGBA(image.Rect(0, 0, chunks_x*16, chunks_y*16))
middle_block_x := chunks_x / 2 * 16
middle_block_y := chunks_y / 2 * 16
for pos := range m.renderedChunks {
px_pos := image.Point{
X: int(pos.X()*16) - middle_block_x + img2.Rect.Dx(),
Y: int(pos.Z()*16) - middle_block_y + img2.Rect.Dy(),
}
draw.Draw(img2, image.Rect(
px_pos.X,
px_pos.Y,
px_pos.X+16,
px_pos.Y+16,
), m.renderedChunks[pos], image.Point{}, draw.Src)
}
img2 := m.ToImage()
buf := bytes.NewBuffer(nil)
bmp.Encode(buf, img2)
os.WriteFile("test.bmp", buf.Bytes(), 0o777)
}
}
func (m *MapUI) ToImage() *image.RGBA {
// get the chunk coord bounds
min, max := m.get_bounds()
chunks_x := int(max[0] - min[0] + 1) // how many chunk lengths is x coordinate
chunks_y := int(max[1] - min[1] + 1)
img2 := image.NewRGBA(image.Rect(0, 0, chunks_x*16, chunks_y*16))
middle_block_x := chunks_x / 2 * 16
middle_block_y := chunks_y / 2 * 16
for pos := range m.renderedChunks {
px_pos := image.Point{
X: int(pos.X()*16) - middle_block_x + img2.Rect.Dx(),
Y: int(pos.Z()*16) - middle_block_y + img2.Rect.Dy(),
}
draw.Draw(img2, image.Rect(
px_pos.X,
px_pos.Y,
px_pos.X+16,
px_pos.Y+16,
), m.renderedChunks[pos], image.Point{}, draw.Src)
}
return img2
}
func (m *MapUI) SetChunk(pos protocol.ChunkPos, ch *chunk.Chunk) {
m.renderQueue.Enqueue(&RenderElem{pos, ch})
m.SchedRedraw()

View File

@ -8,6 +8,7 @@ import (
"hash/crc32"
"image"
"image/draw"
"image/png"
"os"
"path"
"strconv"
@ -53,6 +54,7 @@ type WorldState struct {
ServerName string
worldCounter int
withPacks bool
saveImage bool
packs map[string]*resource.Pack
PlayerPos TPlayerPos
@ -106,6 +108,7 @@ type WorldCMD struct {
Address string
packs bool
enableVoid bool
saveImage bool
}
func (*WorldCMD) Name() string { return "worlds" }
@ -115,6 +118,7 @@ func (p *WorldCMD) SetFlags(f *flag.FlagSet) {
f.StringVar(&p.Address, "address", "", "remote server address")
f.BoolVar(&p.packs, "packs", false, "save resourcepacks to the worlds")
f.BoolVar(&p.enableVoid, "void", true, "if false, saves with default flat generator")
f.BoolVar(&p.saveImage, "image", false, "saves an png of the map at the end")
}
func (c *WorldCMD) Usage() string {
@ -138,6 +142,7 @@ func (c *WorldCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{
w.voidgen = c.enableVoid
w.ServerName = hostname
w.withPacks = c.packs
w.saveImage = c.saveImage
w.ctx = ctx
proxy := utils.NewProxy(logrus.StandardLogger())
@ -424,6 +429,11 @@ func (w *WorldState) SaveAndReset() {
utils.UnpackZip(bytes.NewReader(data), int64(len(data)), pack_folder)
}
if w.saveImage {
f, _ := os.Create(folder + ".png")
png.Encode(f, w.ui.ToImage())
}
// zip it
filename := folder + ".mcworld"