.gif
ffmpeg를 사용하여 화면을 녹화했습니다 . 조금 압축했는데 그래도 gifsicle
꽤 크네요. imagemagick
내 목표는 2프레임마다 1프레임을 제거하여 전체 프레임 수를 절반으로 줄여서 프레임을 더 작게 만드는 것입니다.
gifsicle
을 사용하거나 사용하여 이 작업을 수행할 방법을 찾을 수 없습니다 imagemagick
. man
페이지가 도움이 되지 않습니다.
.gif
애니메이션의 모든 프레임 에서 n
하나의 프레임을 제거하는 방법은 무엇입니까?
답변1
아마도 더 좋은 방법이 있을 것입니다. 하지만 저는 이 방법을 사용하겠습니다.
먼저 애니메이션을 프레임으로 분할합니다.
convert animation.gif +adjoin temp_%02d.gif
그런 다음 작은 for 루프를 사용하여 n 프레임 중 하나를 선택하고 모든 프레임을 반복하여 2로 나눌 수 있는지 확인한 다음, 그렇다면 새 임시 파일에 복사합니다.
j=0; for i in $(ls temp_*gif); do if [ $(( $j%2 )) -eq 0 ]; then cp $i sel_`printf %02d $j`.gif; fi; j=$(echo "$j+1" | bc); done
나눌 수 없는 모든 숫자를 유지하려면(즉, n번째 프레임마다 유지하지 않고 삭제하려는 경우) -eq
로 바꾸세요 -ne
.
완료되면 선택한 프레임에서 새 애니메이션을 만듭니다.
convert -delay 20 $( ls sel_*) new_animation.gif
convert.sh
이런 작은 스크립트를 쉽게 만들 수 있습니다
#!/bin/bash
animtoconvert=$1
nframe=$2
fps=$3
# Split in frames
convert $animtoconvert +adjoin temp_%02d.gif
# select the frames for the new animation
j=0
for i in $(ls temp_*gif); do
if [ $(( $j%${nframe} )) -eq 0 ]; then
cp $i sel_`printf %02d $j`.gif;
fi;
j=$(echo "$j+1" | bc);
done
# Create the new animation & clean up everything
convert -delay $fps $( ls sel_*) new_animation.gif
rm temp_* sel_*
그런 다음 예를 들어 전화하십시오.
$ convert.sh youranimation.gif 2 20
답변2
대체 버전이 있습니다막 생물 반응기bash 함수로서의 대답은 다음과 같습니다.
gif_framecount_reducer () { # args: $gif_path $frames_reduction_factor
local orig_gif="${1?'Missing GIF filename parameter'}"
local reduction_factor=${2?'Missing reduction factor parameter'}
# Extracting the delays between each frames
local orig_delay=$(gifsicle -I "$orig_gif" | sed -ne 's/.*delay \([0-9.]\+\)s/\1/p' | uniq)
# Ensuring this delay is constant
[ $(echo "$orig_delay" | wc -l) -ne 1 ] \
&& echo "Input GIF doesn't have a fixed framerate" >&2 \
&& return 1
# Computing the current and new FPS
local new_fps=$(echo "(1/$orig_delay)/$reduction_factor" | bc)
# Exploding the animation into individual images in /var/tmp
local tmp_frames_prefix="/var/tmp/${orig_gif%.*}_"
convert "$orig_gif" -coalesce +adjoin "$tmp_frames_prefix%05d.gif"
local frames_count=$(ls "$tmp_frames_prefix"*.gif | wc -l)
# Creating a symlink for one frame every $reduction_factor
local sel_frames_prefix="/var/tmp/sel_${orig_gif%.*}_"
for i in $(seq 0 $reduction_factor $((frames_count-1))); do
local suffix=$(printf "%05d.gif" $i)
ln -s "$tmp_frames_prefix$suffix" "$sel_frames_prefix$suffix"
done
# Assembling the new animated GIF from the selected frames
convert -delay $new_fps "$sel_frames_prefix"*.gif "${orig_gif%.*}_reduced_x${reduction_factor}.gif"
# Cleaning up
rm "$tmp_frames_prefix"*.gif "$sel_frames_prefix"*.gif
}
용법:
gif_framecount_reducer file.gif 2 # reduce its frames count by 2