Monorepo for Tangled
Something went wrong. Try again.
Go
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889package ico
import ( "bytes" "encoding/binary" "fmt" "image" "image/png")
type IconDir struct { Reserved uint16 // must be 0 Type uint16 // 1 for ICO, 2 for CUR Count uint16 // number of images}
type IconDirEntry struct { Width uint8 // 0 means 256 Height uint8 // 0 means 256 ColorCount uint8 Reserved uint8 // must be 0 ColorPlanes uint16 // 0 or 1 BitsPerPixel uint16 SizeInBytes uint32 Offset uint32}
func ImageToIco(img image.Image) ([]byte, error) { // encode image as png var pngBuf bytes.Buffer if err := png.Encode(&pngBuf, img); err != nil { return nil, fmt.Errorf("failed to encode PNG: %w", err) } pngData := pngBuf.Bytes()
// get image dimensions bounds := img.Bounds() width := bounds.Dx() height := bounds.Dy()
// prepare output buffer var icoBuf bytes.Buffer
iconDir := IconDir{ Reserved: 0, Type: 1, // ICO format Count: 1, // One image }
w := uint8(width) h := uint8(height)
// width/height of 256 should be stored as 0 if width == 256 { w = 0 } if height == 256 { h = 0 }
iconDirEntry := IconDirEntry{ Width: w, Height: h, ColorCount: 0, // 0 for PNG (32-bit) Reserved: 0, ColorPlanes: 1, BitsPerPixel: 32, // PNG with alpha SizeInBytes: uint32(len(pngData)), Offset: 6 + 16, // Size of ICONDIR + ICONDIRENTRY }
// write IconDir if err := binary.Write(&icoBuf, binary.LittleEndian, iconDir); err != nil { return nil, fmt.Errorf("failed to write ICONDIR: %w", err) }
// write IconDirEntry if err := binary.Write(&icoBuf, binary.LittleEndian, iconDirEntry); err != nil { return nil, fmt.Errorf("failed to write ICONDIRENTRY: %w", err) }
// write PNG data directly if _, err := icoBuf.Write(pngData); err != nil { return nil, fmt.Errorf("failed to write PNG data: %w", err) }
return icoBuf.Bytes(), nil}