Elixir doesn’t have built-in library for image processing

So, the package from Erlang is used. erlang egd

# Just for the context
defmodule Identicon.Image do
	defstruct hex: nil, color: nil **pixel_map: nil**
end

defmodule Identicon do
	def main(input) do
		input
		|> hash_input
		|> pick_color
		|> build_grid
		|> filter_odd_squares
		**|> build_pixel_map
		|> draw_image
		|> save_image(input) #here, input is the second argument (file name)**
	end

	**def save_image(image, input) do
		File.write("#{input}.png", image)
	end**

	**def draw_image(%Identicon.Image{color: color, pixel_map: pixel_map}) do
		# even if struct `image` is fed, if the instance `image` is not used,
		# only applying patter matching is also valid!
		image = :egd.create(250, 250) #create a canvas
		fill = :egd.color(color)

		Enum.each pixel_map, fn({start, stop}) -> # doing some processing per each element (but not transforming; different to map)
			:edg.filledRectangle(image, start, stop, fill) # modifying object (image) inplace
		end
	end**

	**def build_pixel_map(%Identicon.Image{grid: grid} = image) do
		pixel_map = Enum.map grid, fn({ _code, index }) ->
												# underscore means we don't care			
			horizontal = rem(index, 5) * 50  # 50 pixels, and 5 rectangles
			vertical = div(index, 5) * 50
			top_left = {horizontal, vertical}
			bottom_right = {horizontal + 50, vertical + 50}
			
			{top_left, bottom_right}
		end

		%Identicon.Image{image | pixel_map: pixel_map}
	end**

	def filter_odd_squares(%Identicon.Image{grid: grid} = image) do
		Enum.filter grid, fn({code, _index}) ->
			rem(code, 2) == 0 # divisible by 2, then it's 0

		end

	def build_grid(%Identicon.Image{hex: hex} = image) do
		grid =
			hex
				|> Enum.chunk(3)
				|> Enum.map(&mirror_row/1) 
				|> List.flatten # no nested logic
				|> Enum.with_index 
	
		%Identicon.Image{image | grid: grid}
	end

def mirror_row(row) do
	[first, second | _tail] = row

	row ++ [second, first]
end

	def pick_color(%Identicon.Image{hex: [r,g,b | _tail} = image ) do
		%Identicon.Image{image | color: {r, g, b}}
	end

	def hash_input(input) do
		hex = :crypto.hash(:md5, input)
		|> :binary.bin_to_list

		%Identicon.Image{hex: hex}
	end
end

def build_grid(%Identicon.Image{hex: hex} = image) do
	grid =
		hex
			|> Enum.chunk(3)
			|> Enum.map(&mirror_row/1) 
			|> List.flatten 
			|> Enum.with_index 

	%Identicon.Image{image | grid: grid}
end

def mirror_row(row) do
	[first, second | _tail] = row

	row ++ [second, first]
end