एनिमेटेड जिफ से हर दूसरे फ्रेम को कैसे निकालें?


22

मेरे पास वीडियो से भरा एक फ़ोल्डर है जिसे मैं एनिमेटेड जिफ़ में बदलना चाहता हूं। ffmpeg / avconv इसे सीधे करने का एक बुरा काम करता है, इसलिए मैं वीडियो को पहले एक फ्रेम के रूप में प्रत्येक फ्रेम में आउटपुट करके gif में परिवर्तित करता हूं और फिर imagemagick का उपयोग करके वापस gif में परिवर्तित करता हूं। समस्या यह है कि यह फ़ाइल आकार के मामले में बड़े जीआईएफ के परिणामस्वरूप है। इसे हल करने के लिए मैं gif से हर दूसरे या nth फ्रेम को "ड्रॉप" करना चाहता हूं, या तो gif में कनवर्ट करते समय या gif से फ्रेम हटाते समय हर इमेज फाइल को स्किप कर देता हूं। मैं इमेजमगिक या कुछ अन्य कमांड-लाइन उपयोगिता का उपयोग करके उबंटू (13.04) पर यह कैसे कर सकता हूं?

जवाबों:


14

एक बैश स्क्रिप्ट का उपयोग करना

कमांड लाइन से ऐसा करने के लिए, आप Gifsicle नामक एक उपयोगिता का उपयोग कर सकते हैं । हर दूसरे फ्रेम को हटाने के लिए कोई विधि नहीं बनाई गई है, इसलिए आपको कुछ स्क्रिप्टिंग के साथ अपने हाथों को गंदा करना होगा।

यहाँ एक त्वरित स्क्रिप्ट है जिसे मैंने केवल एक GIF करने के लिए बनाया है:

#!/bin/bash
# This script will take an animated GIF and delete every other frame
# Accepts two parameters: input file and output file
# Usage: ./<scriptfilename> input.gif output.gif

# Make a copy of the file
cp $1 $2

# Get the number of frames
numframes=`gifsicle $1 -I | grep -P "\d+ images" --only-matching | grep -P "\d+" --only-matching`

# Deletion
let i=0
while [[ $i -lt $numframes  ]]; do
    rem=$(( $i % 2 ))

    if [ $rem -eq 0 ]
    then
        gifsicle $2 --delete "#"$(($i/2)) -o $2 
    fi

    let i=i+1 
done

मैंने एक साधारण उलटी गिनती GIF के साथ इसका परीक्षण किया:

यहां छवि विवरण दर्ज करें

और यह स्क्रिप्ट के माध्यम से चलाने के बाद परिणाम है:

यहां छवि विवरण दर्ज करें

यह स्क्रिप्ट बेशक बुलेटप्रूफ नहीं है, लेकिन यह आपको सही दिशा में ले जानी चाहिए।


ध्यान दें कि आपके विलोपन लूप को सरल बनाया जा सकता हैlet i=0; while [[ $i -lt $(($numframes / 2)) ]]; do gifsicle $2 --delete "#$i" -o $2; let i=i+1; done
इल्मरी करोनन

1
वास्तव में, आपको एक लूप की आवश्यकता नहीं है: gifsicle "$1" --unoptimize $(seq -f "#%g" 0 2 $numframes) -O2 -o "$2"यह एक कॉल में करेगा।
इल्मरी करोनें

मैं वास्तव में कमांड लाइन से इस स्क्रिप्ट को चलाने का तरीका नहीं जानता। मैंने इसे gifdrop.sh फ़ाइल के रूप में सहेजने और इसे उपयोग में बताए अनुसार चलाने की कोशिश की (./gifdrop.sh in.gif out.gif) एक gif in.gif पर और इसे अज्ञात कमांड gifdrop कहा
mheavers

क्या आपने फ़ाइल को निष्पादन योग्य बनाया है? chmod +x gifdrop.sh
जॉन बी

1
MacOS पर बेहतर काम करता है: github.com/colindean/hejmo/blob/master/scripts/… - मेरा संस्करण जो grep के बजाय पर्ल का उपयोग करता है ताकि यह macOS पर काम करे जिसमें जीएनयू grep डिफ़ॉल्ट रूप से स्थापित न हो। इसके अलावा, फ़ाइल नाम में रिक्त स्थान को संभालता है।
कॉलिन डीन

27

यहाँ का उपयोग कर एक सरल समाधान है gifsicle JohnB की स्क्रिप्ट से:

gifsicle -U input.gif `seq -f "#%g" 0 2 99` -O2 -o output.gif

यह कमांड अधिकांश यूनिक्स गोले में काम करना चाहिए; मैंने इसे बैश में परखा है। बदलें input.gifऔर output.gifइनपुट और आउटपुट फ़ाइल नामों के 99साथ , और आपके एनीमेशन में फ़्रेम की संख्या के साथ। (एक बड़ी संख्या का उपयोग करना ठीक है, लेकिन जिफिसल इसके बारे में शिकायत करेगा।)

कुछ नोट:

  • -Uस्विच पूर्ववर्ती लोगों के साथ इनपुट एनीमेशन में फ्रेम में मर्ज हो जाएगी, ताकि प्रत्येक फ्रेम अकेला खड़ा है और किसी भी अन्य लोगों में निर्भर नहीं करता है। आप वास्तव में एनिमेशन के साथ बहुत कुछ करने से पहले ऐसा करना चाहते हैं, अन्यथा आपको गड़बड़ परिणाम मिलने की संभावना है। (यदि आपका इनपुट एनीमेशन पहले से ही अनधिकृत है, तो gifsicle इसके बारे में चेतावनी छाप सकता है, लेकिन यह भी पूरी तरह से हानिरहित है।)

  • इसके विपरीत, -O2स्विच फ़ाइल आकार को कम करने के लिए आउटपुट एनीमेशन का पुनः अनुकूलन करता है। JohnB के सैंपल एनीमेशन के साथ, यह आउटपुट साइज़ को 27% कम कर देता है।

  • seqआदेश सिर्फ 0 से 99 के लिए संख्या का एक अनुक्रम आउटपुट, 2. चरणों में गिनती -f "#%g"बनाता है यह एक मुद्रित #प्रत्येक संख्या है, जो gifsicle एक फ्रेम चयन के बजाय एक फ़ाइल नाम के रूप में यह समझ में बनाता है पहले। Seq `कमांड के चारों ओर backticks ( ) इसके आउटपुट को gifsicle कमांड लाइन में पैरामीटर के रूप में शामिल करने का कारण बनता है।

यदि आप नहीं चाहते कि gif की गति gifsicle -I input.gifबढ़े , तो आप वर्तमान फ़्रेम विलंब को प्राप्त करने के लिए उपयोग कर सकते हैं , इसे 2 से गुणा करें और उपयोग करें gifsicle -d ${delay} ...


अच्छी तरह से किया! यदि आप वास्तव में चाहते थे, तो आप सही तरीके से फ्रेम की संख्या देने के लिए मेरी स्क्रिप्ट से grep का उपयोग कर सकते हैं (और एक कमांड का एक बीहोम बना सकते हैं)। या शायद एक एनिमेटेड GIF में फ़्रेम की संख्या को वापस करने का एक सरल तरीका है?
जॉनबी

3
मैंने एक आदेश का पालन करते हुए, @JohnB -gifsicle input.gif `seq -f "#%g" 0 2 $(identify input.gif | tail -1 | cut -d "[" -f2 - | cut -d "]" -f1 -)` --unoptimize -O2 -o output.gif
कसरा रहजर्दी

संस्करण 1.71 के साथ विंडोज 7 x64 पर, मुझे मिला useless unoptimization-related input option:। इसलिए मैंने इसे दो चरणों में किया (गेट बैश के भीतर से): 1. gifsicle -U -o unoptimized.gif input.gif2.gifsicle unoptimized.gif `seq -f "#%g" 0 2 99` -O2 -o output.gif
फेकली

11

नोट : यह उत्तर एक कमांड लाइन / ओपन सोर्स आवश्यकता होने से पहले पोस्ट किया गया था, लेकिन मैं इसे छोड़ रहा हूं क्योंकि यह भविष्य में किसी और की मदद कर सकता है


फ़ोटोशॉप का उपयोग करना

यह एक खुला स्रोत या कमांड लाइन समाधान नहीं है, लेकिन आप फ़ोटोशॉप के साथ ऐसा कर सकते हैं:

फ़ाइलआयातपरतें करने के लिए वीडियो फ्रेम्स ...

वीडियो आयात करें

" लिमिट टू एवरी __ फ्रेम्स " आपके लिए ट्रिक करेगा


0

यहाँ बैच स्क्रिप्ट प्रसंस्करण का उपयोग कर मेरा समाधान है ...

सबसे पहले कैप्चर किए गए मूल एनिमेटेड gif को input.gif फ़ाइल में कॉपी करें और फिर कमांड दुभाषिया शुरू करें और टाइप करें:

gifsicle input.gif -I "# -1"> input.txt

input.txt में देखें और देखें कि एनीमेशन की लंबाई क्या है - इसमें कितने फ्रेम हैं ...

input.txt:

* input.gif 166 images
  logical screen 1366x768
  global color table [256]
  background 15
  loop forever
  + image #165 1x1 at 1365,767 transparent 15
    disposal asis delay 0.07s

तब एडिट-क्रिएट test.bat और वैरिएबल लेन की वैल्यू बदलें = निर्दिष्ट करें_length_number_from_input.txt और test.bat सहेजें ...

test.bat:

@echo off
set /A len=166
set /A i=1
set /A ii=0
:loop
if %i%==%len% goto :eof
if %ii%==0 (set /A ii=1) else (set /A ii=0)
set /A iii=%ii%*%i%
if %i%==%iii% echo gifsicle -b input.gif --delete "#1" --done
set /A i=%i%+1
goto :loop

फिर अंत में process1.bat और process2.bat शुरू करें और हर विषम फ्रेम वाले कटे हुए एनिमेशन को फाइल इनपुट में संसाधित किया जाएगा। Gif

process1.bat:

gifsicle -b -U input.gif
test.bat > input.bat

process2.bat:

call "input.bat"
gifsicle -b -O2 input.gif
erase "input.bat"

0

मुझे लगता है कि मुझे नई और अधिक परिष्कृत व्याख्या की आवश्यकता है (फ्रेम विलंब भी महत्वपूर्ण बात है जिसे बहुत महत्वपूर्ण माना जाना चाहिए) ... इस नई प्रक्रिया के लिए आपको इस लिंक से JREPL.BAT डाउनलोड करना होगा: http://www.dostips.com /forum/viewtopic.php?t=6044

सबसे पहले copy gif को input.gif फ़ाइल में कैद करें, फिर कमांड इंटरप्रेटर शुरू करें और टाइप करें:

gifsicle input.gif -I "# -1"> input.txt

input.txt में देखें और देखें कि एनीमेशन की लंबाई क्या है - इसमें कितने फ्रेम हैं ... फ्रेम की देरी पर भी ध्यान दें और यदि इसके 0.07s का अर्थ है कि आपको विकल्प -d14 (7msec * 2) को इस पंक्ति में रखना चाहिए process.cmd में: gifsicle -b -U -d14 input.gif, save process.cmd संपादित करने के बाद

फिर एनीमेशन के फ्रेम की संख्या से मिलान करने के लिए इस लाइन से टेस्ट 166 और परिवर्तन मान का परिवर्तन करें: एनिमेशन के फ़्रेमों की संख्या से मेल खाने के लिए: / L %% i IN (1,2,166) DO "# %% i" >> input.bat, के बाद सहेजें test.bat संपादित करें ...

फिर शुरू करें। हर विषम फ्रेम के साथ cmd और क्रॉप्ड एनीमेशन को फाइल input.gif में संसाधित किया जाएगा

PS इस पद्धति का लाभ यह भी है कि आपको इस बात का पूरा नियंत्रण है कि आप gif (हर दूसरा फ्रेम (1,2,166), या हर तीसरे (1,3,166)) से क्या हटाना चाहते हैं, और इसी तरह सिर्फ मध्य संख्या को बदलें बैच लाइन, लेकिन ध्यान रखें कि यदि आप (1,3,166) को निर्दिष्ट करते हैं, तो आपको तदनुसार परिवर्तन (7msec * 3/2 = 10) को प्रतिबिंबित करने के लिए process.cmd से -14 (देरी विकल्प) बदलना चाहिए, इसलिए (7msec) 2 के बजाय / 1 = 14), देरी के लिए विकल्प होना चाहिए -10 ...

अन्य फाइलें (हर दूसरे फ्रेम को हटाने के उदाहरण के लिए): test.bat:

@echo off
echo gifsicle -b input.gif --delete>> input.bat
for /L %%i IN (1,2,166) DO echo  "#%%i">> input.bat
echo  --done>> input.bat
call jrepl.bat "\n" "" /x /m /f input.bat /o -

प्रक्रिया। cmd:

gifsicle -b -U -d14 input.gif
call "test.bat"
call "input.bat"
gifsicle -b -O3 input.gif
erase "input.bat"

और हेल्पर readme फ़ाइल input.txt:

* input.gif 166 images
  logical screen 1366x768
  global color table [256]
  background 15
  loop forever
  + image #165 1x1 at 1365,767 transparent 15
    disposal asis delay 0.07s
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.