代码之家  ›  专栏  ›  技术社区  ›  David Rutten

绘图的快速CRC。位图

  •  1
  • David Rutten  · 技术社区  · 15 年前

    在应用程序启动时,我构建一个图标缓存(24x24 32bbp预乘argb位图)。这个缓存包含大约一千个项目。出于内存和性能的原因,我不想在这个缓存中多次存储同一个映像。我认为最好的方法是在每个位图进入缓存时从中创建某种CRC,并将新的位图与此CRC列表进行比较。

    从只加载在内存中的位图创建CRC的好方法(也是快速方法)是什么?

    或者我完全走错了轨道,有没有更好的方法来构建位图缓存?

    2 回复  |  直到 15 年前
        1
  •  2
  •   Andras Zoltan    15 年前

    虽然我会重复汉斯所说的话,但我相信你可以做到,但CRC是一种不好的算法。

    您可以创建生成位图字节的MD5哈希。根据我的计算,您的图像大小必须至少为2 KB。要生成散列,您可以在整个位图中计算它,也可以在每个 n th字节——在散列方面会更快,但在内存使用上可能会更重,因为您必须将这些字节提取到新的数组中。

    如果你想跳过每N个字节,我将使用4或2-使用4表示你从每个连续像素读取一个组件,使用2表示你从每个连续像素读取两个组件。

    然而,MD5是 非常 很快,您可能会发现(我将在单元测试中对此进行基准测试),只需对整个位图进行哈希运算就可以更快。

    唯一的事情是 我看不出你怎么能提前检查 应该 生成一个给定的位图,而不事先知道它的哈希值,唯一能知道它的哈希值的方法就是生成它。在这种情况下,你最好把新图像保存下来。图像缓存数组中的一个额外元素不会破坏宇宙。

    为了节省空间和启动时间,您真正需要做的是在生成一个图像之前知道它是否与另一个图像相同。假设这些图像是动态生成的,那么当生成两个相同的图像时,它们是由相同的方法调用和相同的参数生成的吗?

    如果是这样,您可以查看用一个或多个哈希代码标记每个生成的图像(使用 object.GetHashCode() ) MethodInfo 生成图像的方法(您可以通过调用 MethodBase.GetCurrentMethod() 以及传入的每个参数的每个哈希代码。该方法的哈希代码非常可靠,因为它使用运行时的方法句柄(每个方法都是唯一的),在64位计算机上,唯一可能发生的哈希代码压缩是64位的,但哈希代码是32。然而,在实践中,这种冲突很少发生,因为应用程序中必须有大量的代码才能使两个单独方法句柄的前32位保持相同。

    当然,除非这些参数类型具有良好的散列代码函数,否则单个参数的散列代码的可靠性要低得多。

    这个解决方案决不是完美的(最坏的情况下,你还是会得到一些副本),但我认为它会加快速度。不过,正如我所说,它依赖于您复制的图像总是由相同的调用生成。

        2
  •  1
  •   Hans Passant    15 年前

    CRC与任何哈希函数都有相同的缺陷:一个相等的CRC值 证明图像相同。您的程序将随机(但很少)显示错误的图像。

    你还需要别的东西。类似于从中检索位图的文件名。

    推荐文章