mirror of
https://github.com/taigrr/wails.git
synced 2026-04-02 05:08:54 -07:00
Improved Windows .ico generation
This commit is contained in:
committed by
Lea Anthony
parent
376ba743f4
commit
b003a080b0
127
cmd/package.go
127
cmd/package.go
@@ -16,9 +16,8 @@ import (
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"golang.org/x/image/draw"
|
||||
|
||||
"github.com/jackmordaunt/icns"
|
||||
"golang.org/x/image/draw"
|
||||
)
|
||||
|
||||
// PackageHelper helps with the 'wails package' command
|
||||
@@ -60,83 +59,107 @@ func newPlistData(title, exe, packageID, version, author string) *plistData {
|
||||
}
|
||||
}
|
||||
|
||||
type windowsIconHeader struct {
|
||||
type windowsIcoHeader struct {
|
||||
_ uint16
|
||||
imageType uint16
|
||||
imageCount uint16
|
||||
width uint8
|
||||
height uint8
|
||||
colours uint8
|
||||
_ uint8
|
||||
planes uint16
|
||||
bpp uint16
|
||||
size uint32
|
||||
offset uint32
|
||||
}
|
||||
|
||||
type windowsIcoDescriptor struct {
|
||||
width uint8
|
||||
height uint8
|
||||
colours uint8
|
||||
_ uint8
|
||||
planes uint16
|
||||
bpp uint16
|
||||
size uint32
|
||||
offset uint32
|
||||
}
|
||||
|
||||
type windowsIcoContainer struct {
|
||||
Header windowsIcoDescriptor
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func generateWindowsIcon(pngFilename string, iconfile string) error {
|
||||
header := &windowsIconHeader{
|
||||
imageType: 1,
|
||||
imageCount: 1,
|
||||
bpp: 32,
|
||||
planes: 1,
|
||||
offset: 22,
|
||||
width: 0,
|
||||
height: 0,
|
||||
}
|
||||
sizes := []int{256, 128, 64, 48, 32, 16}
|
||||
|
||||
// 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)
|
||||
outfile, err := os.Create(iconfile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer outfile.Close()
|
||||
|
||||
// Write out the header
|
||||
err = binary.Write(outfile, binary.LittleEndian, header)
|
||||
ico := windowsIcoHeader{
|
||||
imageType: 1,
|
||||
imageCount: uint16(len(sizes)),
|
||||
}
|
||||
err = binary.Write(outfile, binary.LittleEndian, ico)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write out the image data
|
||||
_, err = outfile.Write(icondata.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
icons := []windowsIcoContainer{}
|
||||
|
||||
for _, size := range sizes {
|
||||
rect := image.Rect(0, 0, int(size), int(size))
|
||||
rawdata := image.NewRGBA(rect)
|
||||
scale := draw.ApproxBiLinear
|
||||
scale.Scale(rawdata, rect, pngdata, pngdata.Bounds(), draw.Over, nil)
|
||||
|
||||
icondata := new(bytes.Buffer)
|
||||
writer := bufio.NewWriter(icondata)
|
||||
err = png.Encode(writer, rawdata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
writer.Flush()
|
||||
|
||||
imgSize := size
|
||||
if imgSize >= 256 {
|
||||
imgSize = 0
|
||||
}
|
||||
|
||||
data := icondata.Bytes()
|
||||
|
||||
icn := windowsIcoContainer{
|
||||
Header: windowsIcoDescriptor{
|
||||
width: uint8(imgSize),
|
||||
height: uint8(imgSize),
|
||||
planes: 1,
|
||||
bpp: 32,
|
||||
size: uint32(len(data)),
|
||||
},
|
||||
Data: data,
|
||||
}
|
||||
icons = append(icons, icn)
|
||||
}
|
||||
|
||||
offset := uint32(6 + 16*len(sizes))
|
||||
for _, icon := range icons {
|
||||
icon.Header.offset = offset
|
||||
err = binary.Write(outfile, binary.LittleEndian, icon.Header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
offset += icon.Header.size
|
||||
}
|
||||
for _, icon := range icons {
|
||||
_, err = outfile.Write(icon.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user