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

Move structured way to extract a field from image #413

Open
bogdan opened this issue Feb 21, 2025 · 4 comments
Open

Move structured way to extract a field from image #413

bogdan opened this issue Feb 21, 2025 · 4 comments

Comments

@bogdan
Copy link

bogdan commented Feb 21, 2025

Reading image metadata is inconvenient because the return format looks like a result of inspect call:

image = Vips::Image.new_from_file('file.png')
image.get "exif-ifd3-GPSTimeStamp"
    # => "13/1 57/1 0/1 (13:57:00.00, Rational, 3 components, 24 bytes)"
image.get "width" # => 3024
image.get "exif-ifd3-UserComment" 
  # => "Hello (world) (Hello (world), ASCII, 14 components, 14 bytes)"

It can be especially difficult to parse as I can not simply ignore what is in parens all the time because they are not always there, or can be part of the output of text fields.

Is it possible to introduce a different method that would return result in a more structured way like?

image.field("exif-ifd3-UserComment") 
# => {type: :string, value: "Hello (world)", encoding: :ASCII, components: 14, bytes: 14}
@jcupitt
Copy link
Member

jcupitt commented Feb 21, 2025

Hello @bogdan, you're right, the libvips EXIF metadata system is very old now, and not very good.

There's been some discussion about making something better, but no one's done the work yet, unfortunately. The most recent thread on this was:

libvips/libvips#4002

@bogdan
Copy link
Author

bogdan commented Feb 21, 2025

Is there any way we can work it around at the ruby level?

@jcupitt
Copy link
Member

jcupitt commented Feb 22, 2025

libvips puts the raw EXIF data into a binary object called exif-data, so you can always extract that and use any EXIF parse library to read and write values.

$ vipsheader -a ~/pics/k2.jpg | grep exif-data
exif-data: 186 bytes of binary data

Or in ruby:

$ irb
irb(main):001> require "vips"
=> true
irb(main):003> x = Vips::Image.new_from_file "/home/john/pics/k2.jpg"
=> #<Image 1450x2048 uchar, 3 bands, srgb>
irb(main):004> x.get "exif-data"
=> "Exif\x00\x00II*\x00\b\x00\x00\x00\x06\x00\x12\x01\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00\x1A\x01\x05\x00\x01\x00\x00\x00V\x00\x00\x00\e\x01\x05\x00\x01\x00\x00\x00^\x00\x00\x00(\x01\x03\x00\x01\x00\x00\x00\x02\x00\x00\x00\x13\x02\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00i\x87\x04\x00\x01\x00\x00\x00f\x00\x00\x00\x00\x00\x00\x00I\x19\x01\x00\xE8\x03\x00\x00I\x19\x01\x00\xE8\x03\x00\x00\x06\x00\x00\x90\a\x00\x04\x00\x00\x000210\x01\x91\a\x00\x04\x00\x00\x00\x01\x02\x03\x00\x00\xA0\a\x00\x04\x00\x00\x000100\x01\xA0\x03\x00\x01\x00\x00\x00\xFF\xFF\x00\x00\x02\xA0\x04\x00\x01\x00\x00\x00\xAA\x05\x00\x00\x03\xA0\x04\x00\x01\x00\x00\x00\x00\b\x00\x00\x00\x00\x00\x00"

@jcupitt
Copy link
Member

jcupitt commented Feb 22, 2025

... but of course the right fix is to do this at the libvips level, so all language bindings have a better way to interact with EXIF data.

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

No branches or pull requests

2 participants