Как преобразовать модуль erlang (wxImage) const /array в список в Elixir?

#elixir #wxerlang

#elixir #wxerlang

Вопрос:

Я пытаюсь манипулировать «test.jpg «изображение в Elixir с помощью библиотеки Erlang wxImage, но я получаю сообщение об ошибке. Я не знаю, как преобразовать вывод массива / const в список, чтобы я мог использовать его в Elixir.

Также я не знаю, почему возникает ошибка функции предложения, когда синтаксис кажется правильным?

 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. Вы передаете двоичный файл в функцию :wxImage.getData/1 . Если вы посмотрите на документацию для этой функции, она ожидает ссылку на изображение, а не на двоичные данные изображений. Я никогда раньше не пользовался этой библиотекой, но, похоже, вам нужно вызвать :wxImage.loadFile/{2,3,4} , чтобы загрузить изображение из файла. Вероятно, вам также потребуется вызвать new/0 функцию, чтобы сначала получить пустую ссылку на изображение.

2. Я думал, что File.read загружает изображение, и именно поэтому в результате обработки wximage загруженного изображения выводятся числа.

Ответ №1:

Я поиграл с :wxImage и обнаружил пару проблем с вашим кодом:

  1. Вам нужно вызвать :wx.new() to для инициализации wx, прежде чем какая-либо из :wxImage функций заработает.
  2. Аргументом getData/1 должен быть дескриптор изображения, а не данные двоичного файла. Из документов:

wxImage()

Ссылка на объект, представление является внутренним и может быть изменено без предварительного уведомления. Его нельзя использовать для сравнения, хранящегося на диске или распространяемого для использования на других узлах.

И для getData/1 :

getData(This) -> binary()

Types
This = wxImage()

Итак, вы можете сделать это следующим образом:

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

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

  :wx.destroy()
  data
end
  

Но имейте в виду, что bin_to_list/1 вызов выполняется медленно, и я не думаю, что вам это все равно нужно. Вероятно, вы захотите остановиться на :wxImage.new() , сохранить дескриптор в переменной и использовать его для вызова любых других :wxImage функций, которые вам нужны.