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

问题描述 投票:0回答:1

我正在考虑从浏览器实现

Image
类,目前正在实现 ICO 支持。然而,我一直在寻找算法来决定从 ICO 文件中加载哪个图像。

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

const img = new Image()

img.src = 'test.ico'

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

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

  1. Apples favicon 包含 4 个尺寸的图像:32、16、32 和 16。第一个在 Chrome 和 Safari 中使用。
  2. GitHubs favicon 包含 2 个尺寸的图像:16 和 32。第二个在 Chrome 和 Safari 中使用。
  3. Windows98Scaled Icon 02.ico包含14张图片,尺寸:32、16、256、128、48、32、24、16、256、128、48、32、24和16。第三张在Chrome和Safari中都使用。

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

是否有任何标准文件来管理如何做到这一点?或者任何其他可遵循的文档来源?

image browser ico
1个回答
0
投票

根据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
,这不保证相等元素的顺序。

© www.soinside.com 2019 - 2024. All rights reserved.