1 package maps 2 3 import ( 4 "errors" 5 "image" 6 "io" 7 8 "vimagination.zapto.org/minecraft/nbt" 9 ) 10 11 // Encode writes an image an as uncompressed Minecraft map. 12 // 13 // As Minecraft expects the map to be gzip compressed, the Writer sohuld be the 14 // wrapped in gzip.NewWriter 15 func Encode(w io.Writer, i image.Image) error { 16 e := Encoder{ 17 Dimension: -128, 18 Scale: 3, 19 } 20 return e.Encode(w, i) 21 } 22 23 // Encoder lets you specify options for the Minecraft map 24 type Encoder struct { 25 Scale, Dimension int8 26 CenterX, CenterZ int32 27 } 28 29 // Encode writes an image an as uncompressed Minecraft map. 30 // 31 // As Minecraft expects the map to be gzip compressed, the Writer sohuld be the 32 // wrapped in gzip.NewWriter 33 func (e *Encoder) Encode(w io.Writer, im image.Image) error { 34 width := im.Bounds().Dx() 35 height := im.Bounds().Dy() 36 if width > 0xffff || height > 0xffff || width < 0 || height < 0 { 37 return ErrInvalidDimensions 38 } 39 40 colours := make(nbt.ByteArray, 0, width*height) 41 for j := im.Bounds().Min.Y; j < im.Bounds().Max.Y; j++ { 42 for i := im.Bounds().Min.X; i < im.Bounds().Max.X; i++ { 43 colours = append(colours, int8(palette.Index(im.At(i, j)))) 44 } 45 } 46 47 return nbt.Encode(w, nbt.NewTag("", nbt.Compound{ 48 nbt.NewTag("data", nbt.Compound{ 49 nbt.NewTag("scale", nbt.Byte(e.Scale)), 50 nbt.NewTag("dimension", nbt.Byte(e.Dimension)), 51 nbt.NewTag("height", nbt.Short(height)), 52 nbt.NewTag("width", nbt.Short(width)), 53 nbt.NewTag("xCenter", nbt.Int(e.CenterX)), 54 nbt.NewTag("zCenter", nbt.Int(e.CenterZ)), 55 nbt.NewTag("colors", colours), 56 }), 57 })) 58 } 59 60 // Errors 61 var ( 62 ErrInvalidDimensions = errors.New("cannot encode an image with the given dimensions") 63 ) 64