【问题标题】:bash evenly choose 10 numbersbash均匀选择10个数字
【发布时间】:2012-10-16 21:33:34
【问题描述】:

在我目前的问题中,我有数百个动画 gif,它们会执行几次特定的动画,然后在最后一次执行不同的动画。所以这意味着 gif 循环 3 次左右然后在第 4 次而不是循环它会做一个不同的动画。这些循环都只是硬编码到 .gif 文件中的层中。

我的目标是确定第一个循环并将动画缩小为十帧​​。我认为使用 python,我可以找到第一帧何时等于后一帧(从而找到第一个完整序列和帧数)。现在我有了动画拍摄的帧数,这个数字在我正在处理的数百个不同图像中是可变的。所以对于一个图像,第一个循环将在 20 帧左右完成,另一个可能在 25 帧内完成。有些需要 75 帧左右(因为它们是一个非常慢的图像)

我的问题是使用这些数字(20、25、75,...或任何第一个循环)我怎样才能最好地将它变成只有 10。在我的脑海中我做了一些数学运算,这些很好我需要弄清楚如何生成的示例

20 -> 20/10 = 2 Resulting sequence: [0, 20) step 2
25 -> 25/10 = 2.5 Sequenece: [0, 25).... Step ?? should alternate between 2 and 3 somehow
75 -> 75/10 = 7.5 Sequenece: [0, 75).... Step ?? should alternate between 7 and 8 somehow

我的解决方案可以是 bash 脚本或 python 或任何你可以在 bash shell 中使用的东西。

【问题讨论】:

    标签: python image bash animated-gif


    【解决方案1】:

    注意:下面的解决方案较短

    这是一个 Python 迭代器类,可用于生成这些序列:

    class quantizer:
        def __init__(self, total, limit):
            self.total = total
            self.limit = limit
            self.index = float(0)
            self.step = float(total) / float(limit)
        def __iter__(self):
            return self
        def next(self):
            if self.index >= self.total:
                raise StopIteration
            result = int(round(self.index))
            self.index += self.step
            return result
    

    更好的解决方案: 有人向我指出,使用生成器有一个更简洁的解决方案:

    def quantize(total, limit):
        i, step = 0.0, float(total) / float(limit)
        while i < total:
            yield int(round(i))
            i += step
    

    你可以这样使用它:

    >>> for frame in quantize(25, 10):
    ...     print frame
    ... 
    
    0
    3
    5
    8
    10
    13
    15
    18
    20
    23
    >>> 
    

    【讨论】:

    • 太棒了!我想在我接受之前,我会坚持一下,看看我是否能得到一个更受欢迎的 bash 响应,但这已经足够了!
    • 我最终选择了你的,因为它最终是最容易集成的,而且我觉得它产生的数字也非常平衡。
    【解决方案2】:
    # shrink N K -- outputs K (default 10) evenly-spaced integers in the range [0, N)
    shrink() {
      local i k=$((${2:-10} - 1)) n=$(($1 - 1))
      for i in 0 $(seq $k); do echo $((n * i / k)); done
    }
    
    $ echo $(shrink 75)
    0 8 16 24 32 41 49 57 65 74
    $ echo $(shrink 20)
    0 2 4 6 8 10 12 14 16 19
    

    这里有几个假设:

    1. 你总是想要第一帧和最后一帧。

    2. 帧编号从 0 到 n-1。

    (是的,我本可以说for i in $(seq 0 $k)。但我没有。:)

    【讨论】:

      【解决方案3】:

      一个 awk 解决方案。如果您不想从第 0 帧开始,您可以轻松添加偏移量。

      #!/bin/bash
      awk -v ori_f=$1 -v final_f=$2 '
        BEGIN {
          steps=ori_f/final_f
          for (i=0; i<final_f; i++){
            printf "%.0f\n", val
            val=val+steps
          }
        }
      '
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多