ICO图标生成器

免费在线ICO图标生成器,支持PNG/JPG转ICO、自定义尺寸(16x16到512x512)、批量生成多个尺寸。一键生成网站favicon、桌面图标

上传图片

推荐使用正方形图片,支持 PNG、JPG 格式

🖼️
点击或拖拽图片到此处上传
推荐使用正方形图片,支持 PNG、JPG 格式

什么是ICO图标?

ICO(Icon)是Windows系统的图标文件格式,常用于网站favicon、桌面应用程序图标、文件图标等场景。ICO文件可以包含多个不同尺寸的图标,系统会根据显示需求自动选择合适的尺寸。

ICO格式的主要特点

  • 多尺寸支持:单个ICO文件可以包含多个不同分辨率的图标(如16x16、32x32、48x48等)
  • 自动适配:Windows系统会根据显示分辨率自动选择合适的图标尺寸
  • 透明通道:支持PNG格式的透明背景
  • 广泛兼容:所有Windows应用程序都支持ICO格式
  • 体积小巧:相比原始PNG文件,ICO文件通常更小

常见的ICO图标尺寸

尺寸 应用场景
16x16 文件管理器小图标、状态栏图标
32x32 桌面图标、任务栏图标
48x48 控制面板图标、开始菜单
64x64 中等尺寸图标
128x128 大图标、高DPI显示
256x256 超大图标、4K显示

Favicon最佳实践

  • 保持简洁:Favicon尺寸很小,复杂图案难以识别
  • 高对比度:使用高对比度颜色确保在各种背景下清晰可见
  • 多尺寸准备:至少准备16x16、32x32、48x48三个尺寸
  • 使用PNG:相比BMP,PNG支持透明且压缩效果更好
  • 测试显示:在不同浏览器和设备上测试Favicon显示效果

常见问题(FAQ)

Q: 为什么需要多尺寸的ICO图标?

A: 不同场景需要不同尺寸的图标。例如,文件管理器显示16x16小图标,桌面显示32x32中等图标,控制面板显示48x48大图标。包含多个尺寸的ICO文件可以确保在任何场景下都显示清晰。

Q: Favicon应该使用什么尺寸?

A: 推荐Favicon包含以下尺寸:16x16(浏览器地址栏)、32x32(桌面快捷方式)、48x48(Windows资源管理器)。现代浏览器还支持PNG格式的favicon,建议提供32x32或更大的PNG格式。

Q: ICO和PNG有什么区别?

A: ICO是Windows专用的图标格式,可以包含多个尺寸;PNG是通用图像格式,只支持单尺寸。ICO主要用于Windows桌面应用和网站favicon,PNG用于通用图像存储和跨平台显示。

Q: 如何在网站中使用Favicon?

A: 在HTML的<head>标签中添加:<link rel="icon" type="image/x-icon" href="favicon.ico">。也可以同时提供PNG格式:<link rel="icon" type="image/png" href="favicon.png">

代码示例

JavaScript ICO生成示例

// 使用 Canvas 生成ICO格式图标
function generateICO(image, sizes) {
    return new Promise(async (resolve) => {
        const icoData = [];
        const imageData = [];
        let offset = 6 + sizes.length * 16; // Header + Directory Entries
        
        // 为每个尺寸生成PNG数据
        for (const size of sizes) {
            const canvas = document.createElement('canvas');
            canvas.width = size;
            canvas.height = size;
            const ctx = canvas.getContext('2d');
            ctx.drawImage(image, 0, 0, size, size);
            
            const blob = await new Promise(r => canvas.toBlob(r, 'image/png'));
            const arrayBuffer = await blob.arrayBuffer();
            
            imageData.push({
                size: size,
                data: new Uint8Array(arrayBuffer),
                offset: offset
            });
            
            offset += arrayBuffer.length;
        }
        
        // 构建ICO文件头
        // ICO Header: Reserved(2) + Type(2) + Count(2)
        const header = new Uint8Array([0, 0, 1, 0, sizes.length, 0]);
        icoData.push(...header);
        
        // 构建目录条目
        for (const img of imageData) {
            const entry = new Uint8Array(16);
            entry[0] = img.size >= 256 ? 0 : img.size;
            entry[1] = img.size >= 256 ? 0 : img.size;
            entry[4] = 1; // Color planes
            entry[5] = 32; // Bits per pixel
            entry[8] = img.data.length & 0xFF;
            entry[9] = (img.data.length >> 8) & 0xFF;
            entry[10] = (img.data.length >> 16) & 0xFF;
            entry[11] = (img.data.length >> 24) & 0xFF;
            entry[12] = img.offset & 0xFF;
            entry[13] = (img.offset >> 8) & 0xFF;
            entry[14] = (img.offset >> 16) & 0xFF;
            entry[15] = (img.offset >> 24) & 0xFF;
            icoData.push(...entry);
        }
        
        // 添加图像数据
        for (const img of imageData) {
            icoData.push(...img.data);
        }
        
        resolve(new Blob([new Uint8Array(icoData)], { type: 'image/x-icon' }));
    });
}

// 使用示例
const img = new Image();
img.onload = async () => {
    const icoBlob = await generateICO(img, [16, 32, 48]);
    const url = URL.createObjectURL(icoBlob);
    
    // 下载ICO文件
    const a = document.createElement('a');
    a.href = url;
    a.download = 'favicon.ico';
    a.click();
};
img.src = 'icon.png';

Python Pillow ICO生成

from PIL import Image

def generate_ico(input_path, output_path, sizes=None):
    """
    生成ICO图标文件
    :param input_path: 输入图片路径
    :param output_path: 输出ICO文件路径
    :param sizes: 图标尺寸列表,默认包含常用尺寸
    """
    if sizes is None:
        sizes = [16, 32, 48, 64, 128, 256]
    
    img = Image.open(input_path)
    
    # 确保图片是RGBA模式(支持透明)
    if img.mode != 'RGBA':
        img = img.convert('RGBA')
    
    # 为每个尺寸创建图标
    icons = []
    for size in sizes:
        # 调整大小
        resized = img.resize((size, size), Image.LANCZOS)
        icons.append(resized)
    
    # 保存为ICO文件
    icons[0].save(
        output_path,
        format='ICO',
        sizes=[(icon.width, icon.height) for icon in icons]
    )
    
    print(f'ICO文件已生成: {output_path}')
    print(f'包含尺寸: {sizes}')

# 使用示例
generate_ico('icon.png', 'favicon.ico')
generate_ico('logo.jpg', 'app.ico', sizes=[16, 32, 48, 64])

Node.js ICO生成

const sharp = require('sharp');
const fs = require('fs');

async function generateICO(inputPath, outputPath, sizes = [16, 32, 48]) {
    try {
        const images = [];
        
        // 为每个尺寸生成PNG
        for (const size of sizes) {
            const buffer = await sharp(inputPath)
                .resize(size, size, { fit: 'cover' })
                .png()
                .toBuffer();
            images.push(buffer);
        }
        
        // 保存为32x32的PNG作为ICO(现代浏览器也支持PNG作为favicon)
        const icoBuffer = await sharp(inputPath)
            .resize(32, 32, { fit: 'cover' })
            .png()
            .toBuffer();
        
        fs.writeFileSync(outputPath, icoBuffer);
        
        console.log(`ICO文件已生成: ${outputPath}`);
        
        // 为不同尺寸生成单独的文件
        for (let i = 0; i < sizes.length; i++) {
            const filename = outputPath.replace('.ico', `-${sizes[i]}.png`);
            fs.writeFileSync(filename, images[i]);
            console.log(`已生成: ${filename}`);
        }
        
    } catch (error) {
        console.error('生成失败:', error);
    }
}

// 使用示例
generateICO('icon.png', 'favicon.ico');

// 批量生成多个尺寸
async function batchGenerate(inputPath, outputDir) {
    const sizes = [16, 32, 48, 64, 128, 256];
    
    for (const size of sizes) {
        await sharp(inputPath)
            .resize(size, size, { fit: 'cover' })
            .png()
            .toFile(`${outputDir}/icon-${size}x${size}.png`);
        }
    
    console.log('批量生成完成');
}

batchGenerate('icon.png', './output');

Java ImageIO ICO生成

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class ICOGenerator {
    
    public static void generateICO(String inputPath, String outputPath, 
                                     int[] sizes) throws Exception {
        BufferedImage originalImage = ImageIO.read(new File(inputPath));
        
        List icons = new ArrayList<>();
        
        for (int size : sizes) {
            BufferedImage resized = resizeImage(originalImage, size, size);
            icons.add(resized);
        }
        
        // 保存第一个尺寸作为示例(实际ICO格式需要专门的库)
        ImageIO.write(icons.get(0), "PNG", new File(outputPath));
        
        System.out.println("图标生成完成: " + outputPath);
        System.out.println("包含尺寸: " + java.util.Arrays.toString(sizes));
        
        // 为每个尺寸生成单独的PNG文件
        for (int i = 0; i < sizes.length; i++) {
            String filename = outputPath.replace(".ico", 
                "-" + sizes[i] + "x" + sizes[i] + ".png");
            ImageIO.write(icons.get(i), "PNG", new File(filename));
        }
    }
    
    private static BufferedImage resizeImage(BufferedImage original, 
                                              int width, int height) {
        BufferedImage resized = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = resized.createGraphics();
        
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
                          RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.drawImage(original, 0, 0, width, height, null);
        g.dispose();
        
        return resized;
    }
    
    public static void main(String[] args) throws Exception {
        int[] sizes = {16, 32, 48, 64, 128};
        generateICO("icon.png", "favicon.ico", sizes);
    }
}