浏览器如何决定从 ICO 文件加载哪个位图?

How does the browser decide which bitmap to load from an ICO file?

提问人:Linus Unnebäck 提问时间:7/25/2023 更新时间:7/25/2023 访问量:10

问:

我正在考虑从浏览器实现该类,目前正在实现 ICO 支持。但是,我坚持要弄清楚算法来决定要加载ICO文件中的哪个图像。Image

这是我在浏览器中使用的代码:

const img = new Image()

img.src = 'test.ico'

img.onload = () => {
  console.log(img.width, img.height)
  document.body.append(img)
}

在测试一些不同的图像时,我做了以下观察:

  1. 苹果图标包含 4 张大小的图像:32、16、32 和 16。第一个用于 Chrome 和 Safari。
  2. GitHubs 网站图标包含 2 个大小的图像:16 和 32。第二个用于 Chrome 和 Safari。
  3. Windows98缩放图标 02.ico 包含 14 个大小的图像:32、16、256、128、48、32、24、16、256、128、48、32、24 和 16。第三个用于 Chrome 和 Safari。

一种猜测是,它采用具有最大尺寸的第一张图像(例如,首先找到最大尺寸,然后选择与该尺寸匹配的第一张图像)。

是否有任何标准文件来规定应该如何做到这一点?还是任何其他要遵循的文档来源?

图像 浏览器 ICO

评论


答:

0赞 Linus Unnebäck 7/25/2023 #1

根据 Chrome 和 Firefox 的源代码,图像首先根据大小进行优先级排序,其次根据位深度进行优先级排序。

火狐浏览器:

    if (!biggestEntry ||
        (e.mBitCount >= biggestEntry->mBitCount &&
         e.mSize.width * e.mSize.height >=
             biggestEntry->mSize.width * biggestEntry->mSize.height)) {
      biggestEntry = &e;

      if (!desiredSize) {
        mDirEntry = &e;
      }
    }

https://github.com/mozilla/gecko-dev/blob/10a46f9dacc39a9305ef9cbfb27f8b68e25eccc9/image/decoders/nsICODecoder.cpp#L249-L258

铬:

bool ICOImageDecoder::CompareEntries(const IconDirectoryEntry& a,
                                     const IconDirectoryEntry& b) {
  // Larger icons are better.  After that, higher bit-depth icons are better.
  const int a_entry_area = a.size_.width() * a.size_.height();
  const int b_entry_area = b.size_.width() * b.size_.height();
  return (a_entry_area == b_entry_area) ? (a.bit_count_ > b.bit_count_)
                                        : (a_entry_area > b_entry_area);
}

// ...

  // Arrange frames in decreasing quality order.
  std::sort(dir_entries_.begin(), dir_entries_.end(), CompareEntries);

https://github.com/chromium/chromium/blob/a23a83b6c0e9295e10b3d9e88c40da7395df5a18/third_party/blink/renderer/platform/image-decoders/ico/ico_image_decoder.cc#L129-L136


请注意,对于大小和位深度相等的图像,其行为略有不同。Firefox 将始终选择最后一张图片,而 Chrome 则不保证相等元素的顺序。std::sort