mirror of
https://github.com/taigrr/wails.git
synced 2026-04-02 05:08:54 -07:00
intial support for .ico generation
This commit is contained in:
108
cmd/package.go
108
cmd/package.go
@@ -1,9 +1,12 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
|
"image/png"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -13,6 +16,8 @@ import (
|
|||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/image/draw"
|
||||||
|
|
||||||
"github.com/jackmordaunt/icns"
|
"github.com/jackmordaunt/icns"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -55,6 +60,87 @@ func newPlistData(title, exe, packageID, version, author string) *plistData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type windowsIconHeader struct {
|
||||||
|
_ uint16
|
||||||
|
imageType uint16
|
||||||
|
imageCount uint16
|
||||||
|
width uint8
|
||||||
|
height uint8
|
||||||
|
colours uint8
|
||||||
|
_ uint8
|
||||||
|
planes uint16
|
||||||
|
bpp uint16
|
||||||
|
size uint32
|
||||||
|
offset uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateWindowsIcon(pngFilename string, iconfile string) error {
|
||||||
|
header := &windowsIconHeader{
|
||||||
|
imageType: 1,
|
||||||
|
imageCount: 1,
|
||||||
|
bpp: 32,
|
||||||
|
planes: 1,
|
||||||
|
offset: 22,
|
||||||
|
width: 255,
|
||||||
|
height: 255,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load png
|
||||||
|
pngfile, err := os.Open(pngFilename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer pngfile.Close()
|
||||||
|
|
||||||
|
// Decode to internal image
|
||||||
|
pngdata, err := png.Decode(pngfile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale to 256*256
|
||||||
|
rect := image.Rect(0, 0, 255, 255)
|
||||||
|
rawdata := image.NewRGBA(rect)
|
||||||
|
scale := draw.ApproxBiLinear
|
||||||
|
scale.Scale(rawdata, rect, pngdata, pngdata.Bounds(), draw.Over, nil)
|
||||||
|
|
||||||
|
// Convert back to PNG
|
||||||
|
icondata := new(bytes.Buffer)
|
||||||
|
writer := bufio.NewWriter(icondata)
|
||||||
|
err = png.Encode(writer, rawdata)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = writer.Flush()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save size of PNG data
|
||||||
|
header.size = uint32(len(icondata.Bytes()))
|
||||||
|
|
||||||
|
// Open icon file for writing
|
||||||
|
outfilename := filepath.Join(filepath.Dir(pngFilename), iconfile)
|
||||||
|
outfile, err := os.Create(outfilename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer outfile.Close()
|
||||||
|
|
||||||
|
// Write out the header
|
||||||
|
err = binary.Write(outfile, binary.LittleEndian, header)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write out the image data
|
||||||
|
_, err = outfile.Write(icondata.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func defaultString(val string, defaultVal string) string {
|
func defaultString(val string, defaultVal string) string {
|
||||||
if val != "" {
|
if val != "" {
|
||||||
return val
|
return val
|
||||||
@@ -177,14 +263,16 @@ func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
|
|||||||
outputDir := b.fs.Cwd()
|
outputDir := b.fs.Cwd()
|
||||||
basename := strings.TrimSuffix(po.BinaryName, ".exe")
|
basename := strings.TrimSuffix(po.BinaryName, ".exe")
|
||||||
|
|
||||||
// Copy icon
|
// Copy default icon if needed
|
||||||
tgtIconFile := filepath.Join(outputDir, basename+".ico")
|
icon, err := b.copyIcon()
|
||||||
if !b.fs.FileExists(tgtIconFile) {
|
if err != nil {
|
||||||
srcIconfile := filepath.Join(b.getPackageFileBaseDir(), "wails.ico")
|
return err
|
||||||
err := b.fs.CopyFile(srcIconfile, tgtIconFile)
|
}
|
||||||
if err != nil {
|
|
||||||
return err
|
// Generate icon from PNG
|
||||||
}
|
err = generateWindowsIcon(icon, po.BinaryName+".ico")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy manifest
|
// Copy manifest
|
||||||
@@ -243,7 +331,7 @@ func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *PackageHelper) copyIcon(resourceDir string) (string, error) {
|
func (b *PackageHelper) copyIcon() (string, error) {
|
||||||
|
|
||||||
// TODO: Read this from project.json
|
// TODO: Read this from project.json
|
||||||
const appIconFilename = "appicon.png"
|
const appIconFilename = "appicon.png"
|
||||||
@@ -268,7 +356,7 @@ func (b *PackageHelper) copyIcon(resourceDir string) (string, error) {
|
|||||||
|
|
||||||
func (b *PackageHelper) packageIconOSX(resourceDir string) error {
|
func (b *PackageHelper) packageIconOSX(resourceDir string) error {
|
||||||
|
|
||||||
srcIcon, err := b.copyIcon(resourceDir)
|
srcIcon, err := b.copyIcon()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -22,6 +22,7 @@ require (
|
|||||||
github.com/stretchr/testify v1.3.0 // indirect
|
github.com/stretchr/testify v1.3.0 // indirect
|
||||||
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba
|
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 // indirect
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 // indirect
|
||||||
|
golang.org/x/image v0.0.0-20200430140353-33d19683fad8
|
||||||
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 // indirect
|
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 // indirect
|
||||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862
|
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862
|
||||||
golang.org/x/text v0.3.0
|
golang.org/x/text v0.3.0
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -70,6 +70,8 @@ golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnf
|
|||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw=
|
||||||
|
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak=
|
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak=
|
||||||
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
|||||||
Reference in New Issue
Block a user