Ejemplo n.º 1
0
// Write the spritesheet image to a file.
func WriteSpriteSheet(img image.Image, folder string, name string, log *golog.Logger) (err error) {
	dir, err := os.Open(folder)
	if err != nil {
		err = os.MkdirAll(folder, 0775)
		if err != nil {
			log.Errorf("Unable to create sprite-sheet output folder '%s'", folder)
			return err
		} else {
			log.Infof("Created sprite-sheet output folder '%s'", folder)
		}
	} else {
		defer dir.Close()
	}

	fullname := filepath.Join(folder, name+".png")
	os.Remove(fullname)
	outFile, err := os.Create(fullname)
	if err != nil {
		log.Errorf("Couldn't create sprite-sheet output file '%s'", fullname)
		return err
	} else {
		defer outFile.Close()
	}
	err = png.Encode(outFile, img)
	if err != nil {
		log.Warningf("Problem writing sprite-sheet to '%s'", fullname)
		return err
	}
	return nil
}
Ejemplo n.º 2
0
// Compose the spritesheet image and return an array of individual sprite data.
func GenerateSpriteSheet(images []Image, log *golog.Logger) (sheet draw.Image, sprites []Sprite) {
	var (
		sheetHeight int = 0
		sheetWidth  int = 0
	)
	sprites = make([]Sprite, 0)

	// calculate the size of the spritesheet and accumulate position and padding
	// data for the individual sprites within the sheet
	for _, img := range images {
		bounds := img.Bounds()

		_, name, factor := IsMagnified(img.Name)
		thisTopPadding := math.Ceil(factor)
		thisBottomPadding := thisTopPadding

		// see if the image dimensions are a multiple of the magnification factor
		fudge := 0
		if math.Mod(float64(bounds.Dy()), factor) != 0 {
			fudge = 1
			log.Warningf("Height of sprite `%s` (%dpx) is not a multiple of its magnification factor (%vx); rounding up to avoid truncated pixels.", name, bounds.Dy(), factor)
		}

		var prevBottomPadding float64
		if len(sprites) == 0 {
			prevBottomPadding = 0
			thisTopPadding = 0
		} else {
			prevBottomPadding = float64(sprites[len(sprites)-1].BottomPadding)
		}

		thisTopPadding = math.Max(thisTopPadding, prevBottomPadding)
		thisTopPaddingInt := int(thisTopPadding)
		thisBottomPaddingInt := int(thisBottomPadding)
		newSprite := Sprite{
			name,
			factor,
			thisTopPaddingInt,
			thisBottomPaddingInt,
			image.Rect(0, sheetHeight+thisTopPaddingInt-fudge, bounds.Dx(), sheetHeight+thisTopPaddingInt+bounds.Dy()),
		}
		sprites = append(sprites, newSprite)
		sheetHeight += bounds.Dy() + thisTopPaddingInt
		if bounds.Dx() > sheetWidth {
			sheetWidth = bounds.Dx()
		}
	}

	// create the sheet image
	sheet = image.NewRGBA(image.Rect(0, 0, sheetWidth, sheetHeight))

	// compose the sheet
	for i, img := range images {
		draw.Draw(sheet, sprites[i].Rectangle, img, image.Pt(0, 0), draw.Src)
	}

	return sheet, sprites
}
Ejemplo n.º 3
0
// Take a folder name, read all the images within, and return them in an array.
func ReadImageFolder(path string, log *golog.Logger) (images []Image, err error) {
	dir, err := os.Open(path)
	if err != nil {
		log.Errorf("Couldn't open folder '%s'", path)
		return nil, err
	} else {
		defer dir.Close()
	}
	dirInfo, err := dir.Stat()
	if err != nil {
		log.Errorf("Couldn't gather information for folder '%s'", path)
		return nil, err
	}
	if !dirInfo.IsDir() {
		// just ignore the request if it isn't a folder
		return nil, nil
	}

	names, err := dir.Readdirnames(0)
	if err != nil {
		log.Errorf("Problem gathering names of image files in '%s'", path)
		return nil, err
	}

	// put these in a canonical order, otherwise it'll be platform-specific
	sort.Strings(names)

	images = make([]Image, 0)
	for _, name := range names {
		fullName := filepath.Join(path, name)
		imgFile, err := os.Open(fullName)
		if err != nil {
			log.Errorf("Couldn't open image file '%s'", fullName)
			continue
		} else {
			defer imgFile.Close()
		}
		imgInfo, err := imgFile.Stat()
		if err != nil {
			log.Errorf("Couldn't gather information for image file '%s'", fullName)
		}
		if imgInfo.IsDir() {
			// skip non-files
			continue
		}
		ext := strings.ToLower(filepath.Ext(name))
		if ext == ".png" {
			img, err := png.Decode(imgFile)
			if err != nil {
				log.Errorf("Problem decoding png image in '%s'", fullName)
				continue
			}
			name = name[0 : len(name)-len(ext)]
			images = append(images, Image{name, img})
		} else if ext == ".jpg" || ext == ".jpeg" {
			img, err := jpeg.Decode(imgFile)
			if err != nil {
				log.Errorf("Problem decoding jpeg image in '%s'", fullName)
				continue
			}
			name = name[0 : len(name)-len(ext)]
			images = append(images, Image{name, img})
		} else {
			log.Debugf("Ignoring unrecognized file '%s'", fullName)
		}
	}

	if len(images) == 0 {
		log.Warningf("Folder '%s' contains no images; no sprite-sheet will be generated", path)
	}

	return images, nil
}