5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-03 06:20:48 +08:00
wails/v3/internal/commands/icons.go
2023-01-22 15:39:57 +11:00

127 lines
2.7 KiB
Go

package commands
import (
"bytes"
"fmt"
"image"
"os"
"strconv"
"strings"
"github.com/jackmordaunt/icns/v2"
"github.com/leaanthony/winicon"
)
type IconsOptions struct {
Example bool `description:"Generate example icon file (appicon.png) in the current directory"`
Input string `description:"The input image file"`
Sizes string `description:"The sizes to generate in .ico file (comma separated)" default:"256,128,64,48,32,16"`
WindowsFilename string `description:"The output filename for the Windows icon" default:"icon.ico"`
MacFilename string `description:"The output filename for the Mac icon bundle" default:"icons.icns"`
}
func GenerateIcons(options *IconsOptions) error {
if options.Example {
return generateExampleIcon()
}
if options.Input == "" {
return fmt.Errorf("input is required")
}
if options.WindowsFilename == "" && options.MacFilename == "" {
return fmt.Errorf("at least one output filename is required")
}
// Parse sizes
var sizes = []int{256, 128, 64, 48, 32, 16}
var err error
if options.Sizes != "" {
sizes, err = parseSizes(options.Sizes)
if err != nil {
return err
}
}
iconData, err := os.ReadFile(options.Input)
if err != nil {
return err
}
if options.WindowsFilename != "" {
err := generateWindowsIcon(iconData, sizes, options)
if err != nil {
return err
}
}
if options.MacFilename != "" {
err := generateMacIcon(iconData, options)
if err != nil {
return err
}
}
return nil
}
func generateExampleIcon() error {
return os.WriteFile("appicon.png", []byte(AppIcon), 0644)
}
func parseSizes(sizes string) ([]int, error) {
// split the input string by comma and confirm that each one is an integer
parsedSizes := strings.Split(sizes, ",")
var result []int
for _, size := range parsedSizes {
s, err := strconv.Atoi(size)
if err != nil {
return nil, err
}
if s == 0 {
continue
}
result = append(result, s)
}
// put all integers in a slice and return
return result, nil
}
func generateMacIcon(iconData []byte, options *IconsOptions) error {
srcImg, _, err := image.Decode(bytes.NewBuffer(iconData))
if err != nil {
return err
}
dest, err := os.Create(options.MacFilename)
if err != nil {
return err
}
defer func() {
err = dest.Close()
if err == nil {
return
}
}()
return icns.Encode(dest, srcImg)
}
func generateWindowsIcon(iconData []byte, sizes []int, options *IconsOptions) error {
var output bytes.Buffer
err := winicon.GenerateIcon(bytes.NewBuffer(iconData), &output, sizes)
if err != nil {
return err
}
err = os.WriteFile(options.WindowsFilename, output.Bytes(), 0644)
if err != nil {
return err
}
return nil
}