2012-10-16 67 views
0

在我目前的問題中,我有幾百個動畫gif,它會執行幾次某種動畫,然後再做一次不同的動畫。因此,這意味着GIF循環第3次左右,然後在第4次,而不是循環它會做不同的動畫。這些循環都只是在.gif文件中硬編碼到圖層中。bash均勻地選擇10個數字

我的目標是確定第一個循環並將動畫縮小爲十個幀。我認爲,使用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中使用的。

回答

2

注:以下

這裏較短的解決方案是一個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 
>>> 
+0

太棒了!我認爲在我接受之前,我會稍微留意一下,看看我能否得到一個更受歡迎的bash響應,但這已經足夠了! – Bob

+0

我最終選擇了你的,因爲它最容易整合,我覺得它生成的數字也很平衡。 – Bob

1
# 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)來代替。但是我沒有。:)

1

一個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 
    } 
    } 
'