Giter Club home page Giter Club logo

Comments (5)

jgraichen avatar jgraichen commented on June 18, 2024

There is a difference between Iptc.Application2.Keywords and Xmp.dc.subject. The first one is a tag that holds a string value, but can appear more than one time. So two keywords can be assigned by adding two key-value pairs:

image.iptc_data.add("Iptc.Application2.Keywords", "kw1")
image.iptc_data.add("Iptc.Application2.Keywords", "kw2")

But Xmp.dc.subject is a multi-value property, that can only be added once but contains multiple string values (XmpBag). Your code example first sets a Xmp.dc.subject with the value "kw1". The second creates a new key-value pair with the new value and tries to add this pair. But only on property Xmp.dc.subject is allowed so the first pair will be overridden.

Currently the only way to assign specific non string values to any kind of property is by providing it in an exiv2 type specific format as a string. For example: exif stores GPS coordinates as an array of rationals. Those values are returned as a string "4/1 22/1 1/3" and can also be written in such a format.

Some quick test told me that the string returned for a multi value XmpBag is a comma separated list, so you can try to just set a comma separated list :

image.iptc_data["Xmp.dc.subject"] = "kw1, kw2"

But I do not know if exiv2 parses and stores such a string as a multi value property or a plain string.

Reading and writing values in there appropriate ruby equivalents (arrays, longs, rationals, ...) isn't easy, due to corner cases and different tags and tag types. I'm working on that at https://github.com/jgraichen/exiv2 if you're interested. Current development build should be able to write multi-value xmp properties as well as reading most values as native ruby objects. Writing native ruby types isn't yet complete. You can take a look in the test cases how native ruby objects are returned.

from exiv2.

Raven24 avatar Raven24 commented on June 18, 2024

Thank you for responding and working on this so quickly!
I had a look at your branch and tested it a little, but it still doesn't seem to cope with multiple values when they are written to the file.

Or, to say it in rspec: (this is what I'd expect)

before do
  # create a fresh test file
  img = Pathname.new("spec/files/test.jpg").to_s
  @test_img = Pathname.new("spec/files/keyword_test.jpg").to_s
  FileUtils.cp(img, @test_img)
end

after do
  # remove test file after test
  FileUtils.rm(@test_img)
end

describe "keywords in 'Xmp.dc.subject'" do 
  it "should accept an array" do
    img = Exiv2::ImageFactory.open(@test_img)
    img.read_metadata
    img.xmp_data["Xmp.dc.subject"] = ["aaaa", "bbbb"]
    img.write_metadata

    img = Exiv2::ImageFactory.open(@test_img)
    img.read_metadata
    img.xmp_data["Xmp.dc.subject"].should =~ ["aaaa", "bbbb"]
  end

  it "should behave like Iptc keywords" do
    img = Exiv2::ImageFactory.open(@test_img)
    img.read_metadata
    img.xmp_data.add("Xmp.dc.subject", "aaaa")
    img.xmp_data.add("Xmp.dc.subject", "bbbb")
    img.write_metadata

    img = Exiv2::ImageFactory.open(@test_img)
    img.read_metadata
    img.xmp_data["Xmp.dc.subject"].should =~ ["aaaa", "bbbb"]
  end
end

I hope this is at all possible.

Btw, adding keywords as img.xmp_data["Xmp.dc.subject"] = "aaaa,bbbb" adds the string without any splitting or other processing by exiv2 :(

from exiv2.

jgraichen avatar jgraichen commented on June 18, 2024

In my opinion the semantic of add is to explicit try to add a new property. Changing that behavior only for Xmp.dc.subject does not look right for me. If your intention is to set multiple keywords the same way you can use the array setter also for Iptc keywords:

    it "should set multiply IPTC data values" do
      @iptc_data["Iptc.Application2.Keywords"] = ["abc", "cde"]
      @iptc_data.to_hash["Iptc.Application2.Keywords"].should == ["abc", "cde"]
    end

The spec name is a little bit old. It will actually set multiple Iptc.Application2.Keywords properties with one keyword each.

If you only want to add a new keyword the following should be possible too:

@iptc_data["Iptc.Application2.Keywords"] += ["efg"]
@iptc_data["Iptc.Application2.Keywords"] << "efg"

Unfortunately that only works if you have at least two keywords previously set (... = ["abc", "cde"]) otherwise not an array but nil or a string will be returned by @iptc_data["Iptc.Application2.Keywords"] which may result in an exception or unwanted behavior.

I'll try to extend the Iptc reading behavior so that an array will be returned for all repeatable Iptc properties even if that property is not set or has only one value but that will need some rewrites.

from exiv2.

Raven24 avatar Raven24 commented on June 18, 2024

In my opinion the semantic of add is to explicit try to add a new property. Changing that behavior only for Xmp.dc.subject does not look right for me.

Ok now I see what you mean by that.

Keep me updated on your progress, I am happy to do some testing for you.

from exiv2.

mrkamel avatar mrkamel commented on June 18, 2024

Hi, is there any progress?
I'm also running into issues because of this.
Thx.

from exiv2.

Related Issues (5)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.