Need help with :egd

I currenly learning Elixir and want to manipulate images with it. I use :egd to calculate sizes of text image that I will render.

My code produces this error:

** (MatchError) no match of right hand side value: []
    (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd_font.erl:62: :egd_font.glyph/2
    (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd_render.erl:601: :egd_render.text_intervals/5
    (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd_render.erl:339: :egd_render.precompile_objects/1
    (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd_render.erl:317: :egd_render.precompile/1
    (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd_render.erl:39: :egd_render.binary/2
    (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd.erl:239: :egd.loop/1

My code:

defmodule ImageText do
  @moduledoc """
  Documentation for `ImageText`.
  """

  def main() do
    render_text("hello")
  end

  def font() do
    :egd_font.load("lib/fonts/font.wingsfont")
  end

  def render_text(text) do
    {image_width, image_height} = calculate_text_size(text)
    image = :egd.create(image_width, image_height)
    :egd.text(image, {0, 0}, font(), String.graphemes(text), :black)
    :egd.save(:egd.render(image), "lib/image.png")
    :egd.destroy(image)
  end

  def calculate_text_size(text) do
    {font_width, font_height} = :egd_font.size(font())

    {font_width * String.length(text), font_height}
  end
end

lib/fonts/font.wingsfont.ttf is https://github.com/erlang/egd/blob/master/priv/fonts/6x11_latin1.wingsfont

I’m afk, so I cannot check this, but have you tried using charlists instead of a bynary when calling load?
that would be changing the quotes to :egd_font.load(‘lib/fonts/font.wingsfont’)
usually this is the first source of troubles when interfacing with erlang

1 Like

I replaced font() with:

def font() do
  :egd_font.load('lib/fonts/font.wingsfont')
end

But it doesn’t change error. You say

have you tried using charlists

and I replaced String.graphemes(text) with String.to_charlist(text), now it produces following traceback:

** (EXIT from #PID<0.246.0>) shell process exited with reason: an exception was raised:
    ** (CaseClauseError) no case clause matching: <<255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
, ...>>
        (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd_png.erl:79: :egd_png.compress_image/4
        (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd_png.erl:73: :egd_png.bitmap2png/4
        (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd_png.erl:62: :egd_png.binary/3
        (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd.erl:240: :egd.loop/1

Interactive Elixir (1.13.0) - press Ctrl+C to exit (type h() ENTER for help)

16:40:22.380 [error] Process #PID<0.285.0> raised an exception
** (CaseClauseError) no case clause matching: <<255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25
5, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, ..
.>>
    (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd_png.erl:79: :egd_png.compress_image/4
    (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd_png.erl:73: :egd_png.bitmap2png/4
    (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd_png.erl:62: :egd_png.binary/3
    (egd 0.10.0) c:/expro/image_text/deps/egd/src/egd.erl:240: :egd.loop/1

It looks like previous problem was solved but new one created :slight_smile:

Welcome to the forum!

It looks like the examples for :egd.text/5 use the erlang string type (the double quote literal). This is shorthand for what Elixir calls a charlist, so that is what you will need to convert your binaries into. But you need to be using this for all your string input:

  • "lib/fonts/font.wingsfont"
  • text
  • "lib/image.png"

Additionally, you are using a literal atom :black. The erl guides actually use an erlang variable for this, Black = egd:color({0,0,0}) (lowercased barewords are atom literals in erlang, uppercase is variables). So I would replace the atom with :egd.color({0,0,0}).

2 Likes

Very thanks, now it works!
this should be rendered image, but I not allowed to upload it :grin:

2 Likes

Yay I’m so glad my shot in the dark worked!