How to convert erlang module (wxImage) const/array to a list in Elixir?

175 views Asked by At

I am trying to manipulate a "test.jpg" image in Elixir by using Erlang wxImage library, but I am getting an error. I do not know how to convert the array/const output to a list so I can use it in Elixir.

Also I do not know why there is a clause function error when the syntax seems to be alright?

defmodule Imedit2 do
  def readimg(image) do
    {:ok, _file} = File.open("happy737.txt", [:write])
    IO.puts("hi there")
    _output =
      image
      |> File.read!()
      |> :wxImage.getData()
      |> to_charlist()

    # IO.puts(is_list(output))
    # IO.puts(is_tuple(output))
    # IO.binwrite(file, output)
    # File.close(file)
  end
end
iex(58)> Imedit2.readimg("test.jpg")
hi there
** (FunctionClauseError) no function clause matching in :wxImage.getData/1

The following arguments were given to :wxImage.getData/1:

    # 1
    <<255, 216, 255, 226, 2, 28, 73, 67, 67, 95, 80, 82, 79, 70, 73, 76, 69, 0, 1,
      1, 0, 0, 2, 12, 108, 99, 109, 115, 2, 16, 0, 0, 109, 110, 116, 114, 82, 71,
      66, 32, 88, 89, 90, 32, 7, 220, 0, 1, 0, 25, ...>>

gen/wxImage.erl:405: :wxImage.getData/1
lib/imedit2.ex:5: Imedit2.readimg/1
1

There are 1 answers

0
Adam Millerchip On BEST ANSWER

I had a play around with :wxImage and I found a couple of problems with your code:

  1. You need to call :wx.new() to to initialize wx before any of the :wxImage functions will work.
  2. The argument togetData/1 should be the image handle, not the binary file data. From the docs:

wxImage()

An object reference, The representation is internal and can be changed without notice. It can't be used for comparsion stored on disc or distributed for use on other nodes.

And for getData/1:

getData(This) -> binary()

Types
This = wxImage()

So you can do it like this:

def readimg(image) do
  :wx.new()

  data =
    image
    |> String.to_charlist()
    |> :wxImage.new()
    |> :wxImage.getData()
    |> :binary.bin_to_list()

  :wx.destroy()
  data
end

But beware that the bin_to_list/1 call is slow, and I don't think you need it anyway. You probably want to stop at :wxImage.new(), keep the handle in a variable, and use that to call whatever other :wxImage functions you need.