【问题标题】:Images packing algorithm in javascriptjavascript中的图像打包算法
【发布时间】:2017-07-20 13:53:49
【问题描述】:

我想创建一个图片列表,就像 Facebook 在您查看相册时所做的那样:

所以,输入数据是:

  1. 我们有一个infinite 已知图像列表widthheight
  2. 我们有一个 container 和一个已知的 width 和无限高
  3. 我们希望按照图像在首选列数上的列出顺序显示图像,调整它们的宽度以适应容器宽度
  4. 有时图像会覆盖一排或两排或多排,例如纵向或横向

一些涵盖可能情况的 ascii 场景:

|------------------|------------------|------------------|
|                  |                  |                  |
|   Normal tile    |    Normal tile   |    Normal tile   |
|                  |                  |                  |
|------------------|------------------|------------------|
|                                     |                  |
|        Landscape tile               |                  |
|                                     |                  |
|------------|------------------------|------------------|
|            |                        |                  |
| Smaller    |  Landscape tile        |    Normal tile   |
|            |                        |                  |
|------------|--|------------------|--|------------------|
|               |                  |                     |
| Portrait tile |    Normal tile   |    Larger tile      |
|               |                  |                     |
|               |------------------|---------------------|
|               |                     |                  |
|               |    Larger tile      |    Normal tile   |
|               |                     |                  |
|---------------|---------------------|------------------|

我考虑过使用 D3 js 中的 Treemap 算法,但我不太确定这是否是正确的选择,因为在我的问题中我不知道容器的高度。

Treemap

这是一个包装问题。

任何帮助或想法将不胜感激!

更新

可以对图像进行缩放或剪裁以更好地适应布局。 因此,例如,如果有一个方形瓷砖可以填充一行并且当前图像是纵向图像,则该算法可以将图像缩放到可用宽度并将其裁剪到可用高度,或者相反。

【问题讨论】:

  • 你可能想看看 Flexbox 网格系统。 philipwalton.github.io/solved-by-flexbox/demos/grids
  • 树形图在这里不是最好的选择。树形图的空洞点根据传入的值和平铺方法动态生成矩形。这显然不是您想要的,因为您已经为每个元素预定义了宽度和高度。
  • 感谢@NicoVanBelle,这似乎是一个很好的资源!
  • whole 点,而不是 hole 点,抱歉(S.O. 确实应该增加编辑 cmets 的 5 分钟宽限期)。
  • 如果瓷砖的水平尺寸非常不稳定,我不会谈论列。我认为,试图去想它们,你是在给自己制造问题。

标签: javascript algorithm d3.js packing


【解决方案1】:

设置最小可接受的平铺区域和行的标准高度。

  1. 按一个显示图像,调整磁贴以使其高度等于行高。如果您没有地方放置下一个瓷砖,我们可以扩展所有完成的行,使其宽度成为最大宽度并转到下一行。我们也可以在不扩展的情况下继续,因为肖像似乎是不可能的。请注意,景观瓷砖不是特例。
  2. 低排。如果图像太低太宽而无法适应行高和宽度,请制作一个图块的低行,使图块的宽度适应行宽。 (您已经忘记了这种情况,这使得在不出现半空行的情况下始终按顺序显示图像是不可能的)您应该将该图像放在最后一个填充行之后,并且具有更低的边框(不扩展肖像)。如果没有这样的行,添加到开头。所以,你必须记住最后添加普通图片的位置,以及最后可以添加低行的位置。
    2.1。低行的另一个可能位置是最后一个缩短的行,其宽度与下一个缩短的行相同。 (寻找肖像)
  3. 如果调整后的图块面积小于可接受的最小值,您将创建肖像。
    3.1。根据最小面积,我们计算肖像的高度 - 以行为单位。此外,它的高度和宽度。
    3.2.由于我们无法真正跟上源顺序,我们将把肖像放在左边。接下来的几行,包括这一行,将被缩短。
    3.3.如果有几幅肖像,从该行开始或继续,则应根据其下边界从最低到最高对其进行排序。不过不管怎样,如果上一排是2高人像开始的,现在又多了一张这样的人像,下一行就会有空隙。
    3.4.如果我们有缝隙,我们会记住它,当我们将来有正常的图片或合适的肖像时,我们会将其插入缝隙中。差距不会很复杂,看下一点。
    3.5.如果大量的人像是可能的(最好认为是可能的),检查未来的图像是否有可能的人像,如果两行超过 1 个,则增加当前的标准行高。此外,当然,将所有找到的肖像移到更高的行。之后,您将标准行高放回原处。

【讨论】:

  • 如果您查看 Facebook 如何显示相册图片,您会发现没有间隙。我的猜测是,能够决定图像的剪裁比例和数量将解决空白问题。
  • 差距出现在创作的某个阶段,而不是最终结果。顺便说一句,你从哪里得到的信息,Facebook 在宽或高图片的任何组合上以这种或那种方式显示图片?你测试过他们的算法吗?您展示的示例是绝对原始的 - 几乎所有图片都是关于正方形的。
猜你喜欢
  • 2021-09-05
  • 1970-01-01
  • 1970-01-01
  • 2010-09-24
  • 2011-06-10
  • 2014-05-02
  • 2015-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多