際際滷

際際滷Share a Scribd company logo
Franz Buchinger, fbuchinger@gmail.com

https://github.com/fbuchinger/pictagger.js
Why tagging matters (not only) for photos
   photo collections usually live in a file/folder system with a
    one-dimensional index
Why tagging matters (not only) for photos
   ... but a multi-dimensional index is needed for better
    retrieveability
   keyword tags are the simplest and most portable approach
    to implement this (-> IPTC Keyword Tag)
Tagging Pitfalls
   ignoring it (95% of all flickr images are probably untagged)
   aspect inconsistency
   term inconsistency/synonyms
Aspect Inconsistency
Aspect Inconsistency




(perspective, country, datecode)  (continent)
Term Inconsistency
Term Inconsistency




 (mountains)  (mountain)
Tagging conveniences
   face detection (automatic, but only considers
    faces)
   drag'n drop tag lists (consistent terms, still
    requires manual assignment)
   --> wanted: automatic tagging system with
    aspect/term consistency
pictagger.js
   Uses existing photo metadata as seed for keyword
    generation
   Frees the user from automatable tagging tasks
   100% Javascript
   Tag generation happens in configurable plugin scripts
    ("taggers")
   works with local and (soon) flickr/picasa-hosted photos
taggers
   request certain metadata/or image data, calculate tags and
    emit them
   taggers only run if the required metadata can be retrieved
   configurable: whole tagger or generation of individual tags
    can be turned on/off
DateTime tagger
{'Photo.Exif.DateTime': "2010:12:21 18:43:00"}




           DateTime Tagger



           [
               'year:2010',
                'season:winter',
                'calweek:50',
                'yearday:345',
                'month:december',
                'day:tuesday',
                'daytime:evening'
           ]
The hello world dayofmylife tagger
PicTagger.App.addTagger({
    namespace: 'doml',
    requires : ['Photo.Exif.Datetime', 'User.Profile.Birthdate'],
    desires : [],
    emits: [
       {predicate: "dayofmylife", label:"day of my life",
        description:"the day of your life the picture was taken",
        active: true}
    ],
    run: function (required, desired){
       var photo_taken = required[0].get('value');
       var user_birthdate = required[1].get('value');
       var ms2Day = 1000*3600*24;
       var doml = Math.ceil((photo_taken - user_birthdate)/ms2Day);
       this.setTag("doml.dayofmylife",doml);
    },
    isActive: true
});
 testing it
domlRequired = [
        new PicTagger.SourceTag({key: 'Photo.Exif.Datetime',
        value: new Date(2011, 1, 1, 13, 49)}),
        new PicTagger.SourceTag({key: 'User.Profile.Birthdate',
        value: new Date(1979, 6, 27)})
    ];
domlTagger.run(domlRequired);
var taggerResult = domlTagger.getTag("doml.dayofmylife").toString();
same(taggerResult, 'dayofmylife:11513');
Tagger Parade I  Time Based
Example Input               Tagger           Example Output
{Photo.Exif.DateTime':      Holiday          ['holiday:easter',
"2010:04:02 18:43:00"}                       'holiday:goodfriday']
{Photo.Exif.DateTime':      Day of my life   ['dayofmylife:11843']
"2010:04:02 18:43:00",
'User.Profile.Birthdate':
"1979:03:23" }
 {'Photo.Exif.DateTime':    DateTime         [
"2010:12:21 18:43:00"}                           'year:2010',
                                                 'season:winter',
                                                 'calweek:50',
                                                 'yearday:345',
                                                 'month:december',
                                                 'day:tuesday',
                                                 'daytime:evening'
                                             ]
Tagger Parade II  Location
Example Input               Tagger     Example Output
{'Photo.Exif.Location':     FromHome   ['kmfromhome:00150',
  {lon: 48.0191752,                     'homebearing:east']
   lat:16.2949365},
'User.Profile.Location':
  {lon: 48.3069400,
   lat: 14.2858300}}
}
{Photo.Exif.Location':      Geohash    ['geohash:u2e94v9egx1']
{lon: 48.0191752
lat:16.2949365}}
   {Photo.Exif.Location':   GeoCode    ['city:vienna',
{lon: 48.0191752                       'province: vienna',
lat:16.2949365}}                       'district:margarethen',
                                       'street:margarethenstra
                                       sse']
Tagger Parade III  Shooting Properties
Example Input                Tagger        Example Output
{'Photo.Exif.Make':          CamType       ['camtype:mobile',
'Apple',                                   'make':'apple','model':
'Photo.Exif.Model':                        'iphone3gs']
'iPhone 3GS'
}
{Photo.Exif.Orientation':    Orientation   ['orientation:portrait'
7}                                         ]
                             Exposure      ['exposure:long']
{Photo.Exif.ExposureTime':
0.4}
Innerds of pictagger.js
   Javascript EXIF Parser (Seidelin 2008), enhanced for HTML 5
    File API
   Backbone.js/underscore.js
   jQuery
Outlook & Questions

More Related Content

Pictagger

  • 2. Why tagging matters (not only) for photos photo collections usually live in a file/folder system with a one-dimensional index
  • 3. Why tagging matters (not only) for photos ... but a multi-dimensional index is needed for better retrieveability keyword tags are the simplest and most portable approach to implement this (-> IPTC Keyword Tag)
  • 4. Tagging Pitfalls ignoring it (95% of all flickr images are probably untagged) aspect inconsistency term inconsistency/synonyms
  • 9. Tagging conveniences face detection (automatic, but only considers faces) drag'n drop tag lists (consistent terms, still requires manual assignment) --> wanted: automatic tagging system with aspect/term consistency
  • 10. pictagger.js Uses existing photo metadata as seed for keyword generation Frees the user from automatable tagging tasks 100% Javascript Tag generation happens in configurable plugin scripts ("taggers") works with local and (soon) flickr/picasa-hosted photos
  • 11. taggers request certain metadata/or image data, calculate tags and emit them taggers only run if the required metadata can be retrieved configurable: whole tagger or generation of individual tags can be turned on/off
  • 12. DateTime tagger {'Photo.Exif.DateTime': "2010:12:21 18:43:00"} DateTime Tagger [ 'year:2010', 'season:winter', 'calweek:50', 'yearday:345', 'month:december', 'day:tuesday', 'daytime:evening' ]
  • 13. The hello world dayofmylife tagger PicTagger.App.addTagger({ namespace: 'doml', requires : ['Photo.Exif.Datetime', 'User.Profile.Birthdate'], desires : [], emits: [ {predicate: "dayofmylife", label:"day of my life", description:"the day of your life the picture was taken", active: true} ], run: function (required, desired){ var photo_taken = required[0].get('value'); var user_birthdate = required[1].get('value'); var ms2Day = 1000*3600*24; var doml = Math.ceil((photo_taken - user_birthdate)/ms2Day); this.setTag("doml.dayofmylife",doml); }, isActive: true });
  • 14. testing it domlRequired = [ new PicTagger.SourceTag({key: 'Photo.Exif.Datetime', value: new Date(2011, 1, 1, 13, 49)}), new PicTagger.SourceTag({key: 'User.Profile.Birthdate', value: new Date(1979, 6, 27)}) ]; domlTagger.run(domlRequired); var taggerResult = domlTagger.getTag("doml.dayofmylife").toString(); same(taggerResult, 'dayofmylife:11513');
  • 15. Tagger Parade I Time Based Example Input Tagger Example Output {Photo.Exif.DateTime': Holiday ['holiday:easter', "2010:04:02 18:43:00"} 'holiday:goodfriday'] {Photo.Exif.DateTime': Day of my life ['dayofmylife:11843'] "2010:04:02 18:43:00", 'User.Profile.Birthdate': "1979:03:23" } {'Photo.Exif.DateTime': DateTime [ "2010:12:21 18:43:00"} 'year:2010', 'season:winter', 'calweek:50', 'yearday:345', 'month:december', 'day:tuesday', 'daytime:evening' ]
  • 16. Tagger Parade II Location Example Input Tagger Example Output {'Photo.Exif.Location': FromHome ['kmfromhome:00150', {lon: 48.0191752, 'homebearing:east'] lat:16.2949365}, 'User.Profile.Location': {lon: 48.3069400, lat: 14.2858300}} } {Photo.Exif.Location': Geohash ['geohash:u2e94v9egx1'] {lon: 48.0191752 lat:16.2949365}} {Photo.Exif.Location': GeoCode ['city:vienna', {lon: 48.0191752 'province: vienna', lat:16.2949365}} 'district:margarethen', 'street:margarethenstra sse']
  • 17. Tagger Parade III Shooting Properties Example Input Tagger Example Output {'Photo.Exif.Make': CamType ['camtype:mobile', 'Apple', 'make':'apple','model': 'Photo.Exif.Model': 'iphone3gs'] 'iPhone 3GS' } {Photo.Exif.Orientation': Orientation ['orientation:portrait' 7} ] Exposure ['exposure:long'] {Photo.Exif.ExposureTime': 0.4}
  • 18. Innerds of pictagger.js Javascript EXIF Parser (Seidelin 2008), enhanced for HTML 5 File API Backbone.js/underscore.js jQuery