file_data 5.2.3 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -2
- data/README.md +22 -49
- data/lib/file_data/formats/exif/exif_data.rb +45 -3
- data/lib/file_data/formats/exif/exif_tags.rb +4 -1
- data/lib/file_data/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f9ac51b8c0f2d6388b07ab1f6614de4a1fac558c21689fa61d198d70c18a8b4
|
4
|
+
data.tar.gz: 4da0fada39336b0346d0846ee6c04a6962c0c4f34909463ded2c0aa2c97511fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74284cdbc2af387ad6e0b058d25ec38ade9bb5021eaec62be513b923ad6a38398ae199698d1aa78226306e3a60856a1c1658b59fe4d460fe7e600345ef555dba
|
7
|
+
data.tar.gz: 3f7a040e99bc6a47da21c759c687f831014ba7e1823f7b63d8e8af2bfb1ab79fb8abbfd5f49059fdb9ad77aa0c0358585f1a935204104597ea580786a46ee6ec
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
file_data (
|
4
|
+
file_data (6.0.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -34,7 +34,6 @@ GEM
|
|
34
34
|
docile (1.1.5)
|
35
35
|
fakefs (0.10.2)
|
36
36
|
ffi (1.9.25)
|
37
|
-
ffi (1.9.25-x64-mingw32)
|
38
37
|
highline (2.0.0)
|
39
38
|
json (2.6.0)
|
40
39
|
method_source (0.9.0)
|
data/README.md
CHANGED
@@ -8,69 +8,42 @@ file_data
|
|
8
8
|
|
9
9
|
Ruby library that reads file metadata.
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
## Basic Usage
|
11
|
+
## Basic Usage for an Exif File
|
14
12
|
|
15
13
|
```ruby
|
16
|
-
|
17
|
-
|
18
|
-
# Get the date when the file content originated. When a photo was taken, when a movie was recorded, etc
|
19
|
-
FileData::FileInfo.origin_date(filepath)
|
20
|
-
|
21
|
-
# Get the date when the file was considered to be created. This is usually tied in some way to when the file itself was created on a disk somewhere (not usually as useful as origin date)
|
22
|
-
FileData::FileInfo.creation_date(filepath)
|
23
|
-
```
|
24
|
-
|
25
|
-
## Advanced Usage
|
14
|
+
require 'file_data'
|
26
15
|
|
27
|
-
|
16
|
+
## Step 1: Read in the exif data using either a file path or a stream
|
28
17
|
|
29
|
-
|
18
|
+
# Using a file path...
|
19
|
+
file_path = '/home/user/desktop/my_file.jpg' # Path to an exif file
|
20
|
+
exif_data = FileData::Exif.all_data(file_path) # read in all of the exif data from the file path
|
30
21
|
|
31
|
-
|
32
|
-
|
33
|
-
|
22
|
+
# Or using a stream...
|
23
|
+
exif_data = File.open(file_path, 'rb') do |f|
|
24
|
+
FileData::Exif.all_data(f)
|
25
|
+
end
|
34
26
|
|
35
|
-
|
27
|
+
## Step 2: Data is divided into image data and thumbnail data. Pick which you want to work with.
|
36
28
|
|
37
|
-
|
38
|
-
|
29
|
+
# Both objects are hash-like and should respond to all hash method except .length which instead will return the value of :Image_Structure_Length,
|
30
|
+
image_data = exif_data.image
|
31
|
+
thumbnail_data = exif_data.thumbnail
|
39
32
|
|
40
|
-
|
41
|
-
# rather than having the file path or stream set in the constructor and the methods
|
42
|
-
# be instance methods to ensure that the user falls into a "pit of success" by only
|
43
|
-
# opening the file once to get tag values rather than potentially multiple times
|
33
|
+
## Step 3: Extract the tag values
|
44
34
|
|
45
|
-
|
46
|
-
hash = FileData::Exif.image_data_only('/path/to/file.jpg')
|
47
|
-
|
48
|
-
# Get thumbnail exif data from a file stream...
|
49
|
-
File.open('/path/to/file.jpg', 'rb') do |f|
|
50
|
-
hash = FileData::Exif.thumbnail_data_only(f)
|
51
|
-
end
|
35
|
+
### Step 3A: Extract tags with a known name (ones that are listed in the "Known Tag Keys" section below)
|
52
36
|
|
53
|
-
|
37
|
+
# Convenience methods are added for the names after the last underscore in the known tag names (casing and underscores are ignored in the convenince method names)
|
54
38
|
|
55
|
-
|
56
|
-
|
57
|
-
# or "#{ifd_id}-#{tag_id}" if there is no existing name for the tag in FileData::ExifTags
|
58
|
-
image_hash = FileData::Exif.image_data_only(file_path_or_stream)
|
59
|
-
image_description_value = image_hash[:Other_ImageDescription]
|
60
|
-
unknown_gps_tag_value = image_hash["34853-99999"]
|
39
|
+
bits_per_sample = image_data.BitsPerSample # Gets :Image_Structure_BitsPerSample from the :Tiff section
|
40
|
+
bits_per_sample = image_data.bits_per_sample # Also gets :Image_Structure_BitsPerSample from the :Tiff section
|
61
41
|
|
62
|
-
|
63
|
-
image_width_tag_value = thumbnail_hash[:Image_Structure_Width]
|
64
|
-
unknown_gps_tag_value = thumbnail_hash["Tiff-99999"]
|
42
|
+
### Step 3B: Extract tags without a known name (ones NOT listed in the "Known Tag Keys" section below)
|
65
43
|
|
66
|
-
|
67
|
-
|
68
|
-
thumbnail_hash = all_data.thumbnail
|
44
|
+
# Use the format "#{ifd_id}-#{tag_id}" for the unknown tag to key into the data
|
45
|
+
unknown_gps_tag_value = image_data["34853-99999"]
|
69
46
|
|
70
|
-
# For extracting only a specific tag the value is returned and the search key must be
|
71
|
-
# an array matching the keys needed to get traverse FileData:ExifTags (see below listing)
|
72
|
-
image_description_value = FileData::Exif.only_image_tag(file_path_or_stream, [:Tiff, 270])
|
73
|
-
unknown_exif_tag_value = FileData::Exif.only_thumbnail_tag(file_path_or_stream, [34665, 2])
|
74
47
|
```
|
75
48
|
|
76
49
|
## Known Tag Keys
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
1
3
|
module FileData
|
2
4
|
# Container for Exif tag values
|
3
5
|
class ExifData
|
@@ -5,12 +7,52 @@ module FileData
|
|
5
7
|
SECTIONS.each { |section| define_method(section[1]) { @hash[section[0]] } }
|
6
8
|
|
7
9
|
def initialize
|
8
|
-
@hash = SECTIONS.each_with_object({}) { |pair, hash| hash[pair[0]] =
|
10
|
+
@hash = SECTIONS.each_with_object({}) { |pair, hash| hash[pair[0]] = ExifHash.new }
|
9
11
|
end
|
10
12
|
|
11
13
|
def add_tag(index, ifd_id, tag_id, tag_value)
|
12
|
-
|
13
|
-
@hash[index][name] = tag_value
|
14
|
+
name_info = ExifTags.get_tag_name(ifd_id, tag_id)
|
15
|
+
@hash[index][name_info.name] = tag_value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Hash with convenience methods for accessing known Exif tag values by name
|
20
|
+
class ExifHash < BasicObject
|
21
|
+
all_tags = ExifTags.tag_groups.values.map{|x| x.values}.flatten
|
22
|
+
tags_map = all_tags.each_with_object({}) do |tag, hash|
|
23
|
+
hash[tag.to_s.split('_').last.upcase] = tag
|
24
|
+
end
|
25
|
+
|
26
|
+
define_method(:method_missing) do |method_name, *args, &block|
|
27
|
+
known_name = tags_map[method_name.to_s.tr('_', '').upcase]
|
28
|
+
|
29
|
+
if known_name.nil?
|
30
|
+
@hash.send(method_name, *args, &block)
|
31
|
+
else
|
32
|
+
@hash[known_name]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
define_method(:respond_to_missing?) do |method_name, include_private|
|
37
|
+
known_name = tags_map[method_name.to_s.tr('_', '').upcase]
|
38
|
+
|
39
|
+
if known_name.nil?
|
40
|
+
@hash.respond_to?(known_name) || super
|
41
|
+
else
|
42
|
+
true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize
|
47
|
+
@hash = {}
|
48
|
+
end
|
49
|
+
|
50
|
+
def [](key)
|
51
|
+
@hash[key]
|
52
|
+
end
|
53
|
+
|
54
|
+
def []=(key, value)
|
55
|
+
@hash[key] = value
|
14
56
|
end
|
15
57
|
end
|
16
58
|
end
|
@@ -1,11 +1,14 @@
|
|
1
1
|
module FileData
|
2
|
+
TagNameInfo = Struct.new(:name, :is_known);
|
3
|
+
|
2
4
|
# Contains tag number to name information taken from the exif spec
|
3
5
|
class ExifTags
|
4
6
|
singleton_class.class_eval { attr_accessor :tag_groups }
|
5
7
|
@tag_groups = {}
|
6
8
|
|
7
9
|
def self.get_tag_name(ifd_id, tag_id)
|
8
|
-
get_known_name(ifd_id, tag_id)
|
10
|
+
known_name = get_known_name(ifd_id, tag_id)
|
11
|
+
TagNameInfo.new(known_name || "#{ifd_id}-#{tag_id}".to_sym, known_name != nil)
|
9
12
|
end
|
10
13
|
|
11
14
|
def self.get_known_name(ifd_id, tag_id)
|
data/lib/file_data/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: file_data
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|