This is a simple server written in Julia that, given an image url, displays images, including animated gifs, in the terminal:
When the server is running, connect with telnet
or nc
:
nc localhost 8888
It will play the gif for about 10 seconds, then ask for more urls until you quit the session
function getframes(image::String, width=40)
# get number of frames
num_frames = int(strip(readall(`identify $image` |> `wc -l`)))
# get pixel data as raw rgb bytes from ImageMagick's convert tool
RGB = int(readbytes(`convert $image -resize $width -coalesce RGB:-`))
# group raw rgb bytes into lists for each pixel: [a,b,c,a,b,c...] -> [[a,b,c][a,b,c]...]
rgb_pixels = [[RGB[i], RGB[i+1], RGB[i+2]] for i=1:3:length(RGB)]
# map rgb pixels into terminal colorspace:
map!(p -> [sum(int(p/50).*[36,6,1])+16], rgb_pixels)
# calculate height and group by frame
height = int(length(rgb_pixels)/width/num_frames)
frame_pixels = [rgb_pixels[int((f-1)*width*height)+1:int(f*width*height)] for f=1:num_frames]
# construct array of rendered images using escape codes
function render(frame)
join(["\e[48;5;$(p[1])m $(if (i%width==0) "\e[0m\n";else "";end)" for (i,p) in enumerate(frame)])
end
return [render(frame) for frame in frame_pixels]
end
# methods for generic function getframes getframes(image::String) getframes(image::String,width) at In[3]:3
# read url from client
function handle_connection(conn)
# read image url
write(conn, "\nEnter image url: ")
url = strip(readline(conn))
frames = getframes(url)
frame_count = length(frames)
# plays ~10 secs of gif based on number of frames
loops = (frame_count==1 || frame_count>100) ? 1 : int(100/frame_count)
# write frames to client
for f in 1:loops
for frame in frames
write(conn, "\n"^80)
write(conn, frame)
sleep(.1)
end
end
end
# methods for generic function handle_connection handle_connection(conn) at In[4]:4
# start server and handle connections
@async begin
server = listen(8888)
while true
sock = accept(server)
@async while true
handle_connection(sock)
end
end
end
Task