Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert reference to binary data (header_value) #16

Closed
kipcole9 opened this issue Sep 18, 2021 · 6 comments · Fixed by #17
Closed

Convert reference to binary data (header_value) #16

kipcole9 opened this issue Sep 18, 2021 · 6 comments · Fixed by #17

Comments

@kipcole9
Copy link
Contributor

kipcole9 commented Sep 18, 2021

Thanks for building this library, amazing work! I'm not an experienced libvips user so apologies if this is a very naive question. I'm aiming to decode the "exif-data" chunk of an image.

iex> Image.header_value img, "exif-data"
{:ok, #Reference<0.2004606776.2701787139.175100>}

If there a way to convert the reference to the underlying binary data? I know I can:

iex> Image.header_value_as_string img, "exif-data"
{:ok,
 "RXhpZgAASUkqAAgAAAAF.....
}

I assume I can then decode_base64 back to the binary blob but that seems more conversion work than necessary.

Is there any way to return the underlying binary blob for a header field?

@kipcole9 kipcole9 changed the title Convert reference to binary data (get-header_value) Convert reference to binary data (header_value) Sep 18, 2021
@akash-akya
Copy link
Owner

akash-akya commented Sep 18, 2021

Hi @kipcole9, thanks for the complements :)

Agree with you. I think just returning the binary blob for Image.header_value makes more sense. Currently, I don't see the need to return ref. I will make changes.

Just curious, you want to just fetch the exif-data blob and parse it outside? I'm asking because you can get parsed exif data fields as strings directly (it uses libexif).

{:ok, field_names} = Vix.Vips.Image.header_field_names(img)

field_names
|> Enum.filter(&String.starts_with?(&1, "exif-if"))
|> Enum.map(fn field_name -> 
  {:ok, value} = Vix.Vips.Image.header_value(img, field_name)
  IO.puts(field_name <> " = " <> value)
end)

I'm not an experienced libvips user so apologies if this is a very naive question

No need, I'm beginner to libvips too :)

@kipcole9
Copy link
Contributor Author

Oh, now I feel a little silly - thanks for the pointer. Yes, I have been doing my own exif decoding (leaning on prior work).

Your example code is very helpful however the return from Vix.Vips.Image.header_value/2 is quite noisy:

iex> {:ok, value} = Vix.Vips.Image.header_value(img, "exif-ifd2-ShutterSpeedValue")
{:ok, "exif-ifd2-ShutterSpeedValue = 8321928/1000000 (8.32 EV (1/320 sec.), SRational, 1 components, 8 bytes)"}

Which seems to be the inherent noisiness of libexif?

Anyway, thanks for the engagement and feel free to close the issue! (look forward to a raw binary return from get_header_value/2 when you get around to it).

@akash-akya
Copy link
Owner

I see. Agree that current output is noisy. Probably this is relevant: kleisauke/net-vips#74 (comment)

If possible, can you try https://github.com/akash-akya/vix/tree/vips-blob branch for the getting the blob as binary?

Tried this

Mix.install([
  {:vix, git: "git@github.com:akash-akya/vix.git", branch: "vips-blob" }
])

{:ok, img} = Vix.Vips.Image.new_from_file("~/Downloads/Canon_DIGITAL_IXUS_400.jpg")
{:ok, exif_data} = Vix.Vips.Image.header_value(img, "exif-data")
File.write!("exif.dat", exif_data)

@kipcole9
Copy link
Contributor Author

Thats great news, thank you. Will try that out in a few hours. I'll stick with doing my own Exif decoding for now since I also need to decode XMP data (and maybe later IPTC data). And it may actually be more efficient since its only one NIF call.

Are you open to PRs to add some additional functions like vips_image_remove() and vips_image_set()?

@kipcole9
Copy link
Contributor Author

Have implemented the vips-blob version. Its perfect for my use case and very fast. Much appreciated.

@akash-akya
Copy link
Owner

akash-akya commented Sep 18, 2021

Nice! I'll close the issue once the change is merged.

Are you open to PRs to add some additional functions like vips_image_remove() and vips_image_set()?

That's great. Yes, all kinds of contributions are welcome.

Thank you for taking time to raise the issue and testing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants