transform png images to gif

The bash shell command Sips supports gif, but i’ve no idea how to create a working gif from a series of png images, using only bash shell scripting or ASObjC

I checked online for solutions but did not find anything useful. Simple image conversions don’t do the trick, as a gif is a short animation and not only a single still image.

Here is a script grabbed on the web years ago

-- Created 2015-08-05  by Takaaki Naganoya
-- Modified 2015-08-06  by Shane Stanley
-- 2015 Piyomaru Software

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set targFormat to "gif" -- was "pdf"
set aImage to choose file of type {"public.image"} with prompt ("Choose image file to convert to " & targFormat & ".")
set aRes to convertImageToANY(aImage, targFormat) of me
--> "/Users/me/Desktop/301b3607.pdf"
--> "/Users/me/Desktop/301b3607_1.pdf" (同一ファイルの変換を2度行った結果、子番号を付与して衝突を回避, 

on convertImageToANY(aImage as alias, outFormat as text)
	set aExt to chkExtension(outFormat) of me
	if aExt = false then return false
	tell application "Finder"
		set bExt to name extension of aImage
	end tell
	set bExt to chkExtension(bExt) of me
	if aExt = bExt then return "There is no need to convert (same format)"
	if bExt = false then return false --出力ファイルフォーマットエラ
	set bImagePosix to POSIX path of aImage
	set bPathString to current application's NSString's stringWithString:bImagePosix
	set newPath to ((bPathString's stringByDeletingPathExtension()) as text) & "." & aExt
	set newPath to chkExistAndAddIncrementalChildNumber(newPath)
	set sText to "sips -s format " & aExt & " " & quoted form of POSIX path of aImage & " --out " & quoted form of newPath
		do shell script sText
	on error erM
		return false --shell scriptの実行時にエラーが発生した
	end try
	return newPath
end convertImageToANY

on chkExtension(aExtension)
	set formatList to {{"jpeg", "jpg"}, {"tiff", "tif"}, {"png"}, {"gif", "giff"}, {"jp2"}, {"pict"}, {"bmp"}, {"qtif"}, {"psd"}, {"sgi"}, {"tga"}, {"pdf"}}
	set hitF to false
	ignoring case
		repeat with i in formatList
			set j to contents of i
			if aExtension is in j then
				set aExt to contents of first item of j
				set hitF to true
				exit repeat
			end if
		end repeat
	end ignoring
	if hitF = false then
		return false --No Hit	
		return aExt --Hit
	end if
end chkExtension

on chkExistAndAddIncrementalChildNumber(aa)
	set aStr to current application's NSString's stringWithString:aa
	set bStr to aStr's lastPathComponent()
	set cStr to (bStr's pathExtension()) as text
	set dStr to (bStr's stringByDeletingPathExtension()) as text
	set eStr to (aStr's stringByDeletingLastPathComponent()) as text
	set aManager to current application's NSFileManager's defaultManager()
	set aRes to (aManager's fileExistsAtPath:aStr) as boolean
	if aRes = false then return aa --重複がない場合、与えられたフルパスをそのまま返す
	set hitF to false
	repeat with i from 1 to 65535
		set tmpPath to (eStr & "/" & dStr & "_" & (i as text) & "." & cStr)
		set tmpStr to (current application's NSString's stringWithString:tmpPath)
		set aRes to (aManager's fileExistsAtPath:tmpStr) as boolean
		if aRes = false then
			set hitF to true
			exit repeat
		end if
	end repeat
	if hitF = false then return false --65,535回繰り返したがファイル名の衝突を回避できなかった、など
	return tmpStr as text
end chkExistAndAddIncrementalChildNumber

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) samedi 27 juin 2020 16:40:25

I don’t think there’s any scripting way of producing animated gifs, other than scripting some app that produces them.

@Shane Stanley
That’s a pity, and sounds definitive.
I read Takaaki’s code moments ago, it converts single images only
Thanks for clarifying

Thanks nevertheless

You can generate animation gif by using convert comannd a part of Image Magic.

Cocoa seems not to supply animation gif generation method.

Some Objective-C projects are seen on Github.

Keynote could make animated GIF…

So import every images as keynote slide… export to GIF.

Keynote support AppleScript.

I tried Maro’s suggestion of Image Magick and it works well. I have Image Magick installed using Homebrew. The below example works for a sequence of numbered tifs (“testgif” folder on external disk “HD1”, files named “testgif001.tif”, “testgif002.tif” etc.) but should automatically work using png files.

Here is the shell command in Terminal:

 convert -delay 20 -loop 0 '/Volumes/HD1/testgif/testgif*.tif' '/Volumes/HD1/testgif.gif'

which can be used in a “do shell script” command in Applescript.

More info:

Browser: Safari 605.1.15
Operating System: macOS 10.14

– So I got interested in making an animated gif palindrome. The result is this script, which I’m sure someone could improve.

-- Example to make an animated gif palindrome
-- kerflooey 20200701a
-- requires homebrew installation of imagemagick
-- "palindrome:" is a disk image volume
-- my image sequence was exported from QT Player 7 as .jpgs

-------------------------------------------------------- set up
set gif_frames_in_FD to "palindrome:gif_frames_in:" as alias
set gif_frames_out_FD to "palindrome:gif_frames_out:" as alias
set gif_palindromeFP to "/Volumes/palindrome/palindrome.gif" --can change filename after created

-------------------------------------------------------- get the frame files in the folder
set all_Files_List to {}
get_All_Files_of_Folder(gif_frames_in_FD, all_Files_List)

-------------------------------------------------------- get rid of DS_Store invisible file. todo: does not begin with period
set allFPs to {}
repeat with aFile in all_Files_List
	if path of aFile does not contain "DS_Store" then
		set end of allFPs to (path of aFile)
	end if
end repeat
-- now we have all the full paths of the frame files

set part1 to simple_sort(allFPs) -- ensure alphabetical sequence

-------------------------------------------------------- need a new file for each frame going backward, except first and last
set part2 to reverse of items 2 thru -2 of allFPs

set allFPs to (part1 & part2) -- now we have the file sequence list; ready to rename and animate

set countFrames to (count allFPs)

-------------------------------------------------------- build matching list of new filenames
set newNamesList to {}
repeat with i from 1 to countFrames
	set newNamesList to ((newNamesList & ("pal_" & ((1000 + i) as string) & ".jpg")))
end repeat

-------------------------------------------------------- dupe and rename
-------------------------------------------------------- ensure gif_frames_out folder is empty before running script
tell application "Finder"
	repeat with i from 1 to countFrames
		set newFile to duplicate ((item i of allFPs) as «class furl») to gif_frames_out_FD with replacing
		set name of newFile to (item i of newNamesList)
	end repeat
end tell

-------------------------------------------------------- make the gif; Q: Will command path be changed w updates?
do shell script ("/usr/local/Cellar/imagemagick/7.0.10-0/bin/convert" & " " & "-delay 10 -loop 0" & " " & "'/Volumes/palindrome/gif_frames_out/*.jpg'" & " " & gif_palindromeFP)

-------------------------------------------------------- HANDLERS

on get_All_Files_of_Folder(gif_frames_in_FD, all_Files_List)
	tell application "System Events"
		--Check each of the files in this disk/folder
		set files_list to (every file of gif_frames_in_FD)
		repeat with i from 1 to (count files_list)
			set end of all_Files_List to item i of files_list
		end repeat
		set sub_folders_list to folders of gif_frames_in_FD
		repeat with the_sub_folder_ref in sub_folders_list
			my get_All_Files_of_Folder(the_sub_folder_ref, all_Files_List)
		end repeat
	end tell
end get_All_Files_of_Folder

on simple_sort(my_list)
	set the index_list to {}
	set the sorted_list to {}
	repeat (the number of items in my_list) times
		set the low_item to ""
		repeat with i from 1 to (number of items in my_list)
			if i is not in the index_list then
				set this_item to item i of my_list as text
				if the low_item is "" then
					set the low_item to this_item
					set the low_item_index to i
				else if this_item comes before the low_item then
					set the low_item to this_item
					set the low_item_index to i
				end if
			end if
		end repeat
		set the end of sorted_list to the low_item
		set the end of the index_list to the low_item_index
	end repeat
	return the sorted_list
end simple_sort

Browser: Safari 605.1.15
Operating System: macOS 10.14