22# File: acdsee.config
33#
44# Description: This config file defines ACDSee XMP region tags for writing.
5+ # The following tags are created in the XMP-acdsee-rs group
56#
6- # Usage: exiftool -config acdsee.config -ACDSEETAG=VALUE FILE ...
7+ # RegionInfoACDSee : The structured tag for the ACDSee regions
8+ # (similar to XMP-mwg-rs:RegionInfo)
9+ #
10+ # The following tags are the width, height, and unit of the
11+ # image at the time of processing when storing image region
12+ # metadata. They are similar to the AppliedToDimensions tags
13+ # of the MWG regions.
14+ # ACDSeeRegionAppliedToDimensionsH : Height of the image
15+ # ACDSeeRegionAppliedToDimensionsUnit : Unit of the image
16+ # ACDSeeRegionAppliedToDimensionsW : Width of the image
17+ #
18+ # Actual region data, stored in an array. These flattened tags
19+ # are treated as List Type tags. There are two region types,
20+ # the ALYArea and the DLYArea. The ALYArea tags tags assigned
21+ # by ACDSee and are usually square in dimensions. The DLYArea
22+ # tags are both the tags assigned by ACDSee (but possibly
23+ # rectangular instead of square) as well as any manual
24+ # assigned tags. They are similar to the area tags of the MWG
25+ # regions.
26+ # ACDSeeRegionDLYAreaH : Height of DLY region
27+ # ACDSeeRegionDLYAreaW : Width of DLY region
28+ # ACDSeeRegionDLYAreaX : X centerpoint of DLY region
29+ # ACDSeeRegionDLYAreaY : Y centerpoint of DLY region
30+ # ACDSeeRegionALYAreaH : Height of ALY region
31+ # ACDSeeRegionALYAreaW : Width of ALY region
32+ # ACDSeeRegionALYAreaX : X centerpoint of ALY region
33+ # ACDSeeRegionALYAreaY : Y centerpoint of ALY region
34+ # ACDSeeRegionName : Name of region
35+ # ACDSeeRegionType : Type of region
36+ # ACDSeeRegionNameAssignType : How the type was assigned.
37+ # "Manual" is the only known
38+ # entry at this time
39+ #
40+ # Conversion tags. These tags can be used to convert other region
41+ # type tags to ACDSee regions.
42+ # MPRegion2ACDSeeRegion : Converts a Microsoft RegionInfoMP
43+ # IPTCRegion2ACDSeeRegion : Converts an IPTC ImageRegion
44+ # MWGRegion2ACDSeeRegion : Converts a MWG RegionInfo
45+ #
46+ # Usage: To set individual tags
47+ # exiftool -config acdsee.config -ACDSEETAG=VALUE FILE ...
48+ #
49+ # To convert Microsoft Regions to ACDSee regions
50+ # exiftool -config acdsee.config "-RegionInfoACDSee<MPRegion2ACDSeeRegion" File ...
51+ # To convert IPTC regions to ACDSee regions
52+ # exiftool -config acdsee.config "-RegionInfoACDSee<IPTCRegion2ACDSeeRegion" File ...
53+ # To convert MWG Regions to ACDSee regions
54+ # exiftool -config acdsee.config "-RegionInfoACDSee<MWGRegion2ACDSeeRegion" File ...
755#
856# Requires: ExifTool version 10.28 or later
957#
1058# Revisions: 2020/01/28 - Bryan K. Williams (aka StarGeek) Created
59+ # 2021/04/08 - BKW Added tags to convert from Microsoft, IPTC,
60+ # and MWG regions to ACDSee regions based upon
61+ # convert_regions.config. Expanded docs.
62+ # Shortened ADCSee tag names and added shortcuts
63+ # from original names to new names, for example
64+ # "RegionInfoACDSeeAppliedToDimensions*" -> "ACDSeeRegionAppliedToDimensions*"
65+ # "RegionInfoACDSeeRegionList* -> "ACDSeeRegion*"
1166#------------------------------------------------------------------------------
67+ use Data::Dumper;
1268
1369my %sACDSeeDimensions = (
1470 STRUCT_NAME => 'ACDSee Dimensions',
1571 NAMESPACE => {'acdsee-stDim' => 'http://ns.acdsee.com/sType/Dimensions#'},
16- 'w' => { Writable => 'real' },
17- 'h' => { Writable => 'real' },
18- 'unit' => { },
72+ 'w' => { Writable => 'real' },
73+ 'h' => { Writable => 'real' },
74+ 'unit' => { },
1975);
2076
2177my %sACDSeeArea = (
@@ -38,14 +94,120 @@ my %sACDSeeRegionStruct = (
3894);
3995
4096%Image::ExifTool::UserDefined = (
41- # new XMP namespaces (eg. xxx) must be added to the Main XMP table:
97+ # new XMP namespaces for ACDSee regions
4298 'Image::ExifTool::XMP::Main' => {
4399 'acdsee-rs' => { # <-- must be the same as the NAMESPACE prefix
44100 SubDirectory => {
45101 TagTable => 'Image::ExifTool::UserDefined::ACDSeeRegions'
46102 },
47103 },
48104 },
105+ 'Image::ExifTool::Composite' => {
106+ # create an ACDSee RegionInfo structure from a Microsoft RegionInfoMP structure
107+ MPRegion2ACDSeeRegion => {
108+ Require => {
109+ 0 => 'RegionInfoMP',
110+ 1 => 'ImageWidth',
111+ 2 => 'ImageHeight',
112+ },
113+ ValueConv => q{
114+ my ($rgn, @newRgns);
115+ foreach $rgn (@{$val[0]{Regions}}) {
116+ my $name = $$rgn{PersonDisplayName};
117+ next unless $$rgn{Rectangle} or defined $name;
118+ my %newRgn = ( Type => 'Face' );
119+ if (defined $name) {
120+ # don't add ignored faces
121+ next if $name eq 'ffffffffffffffff';
122+ $newRgn{Name} = $name;
123+ }
124+ if ($$rgn{Rectangle}) {
125+ my @rect = split /\s*,\s*/, $$rgn{Rectangle};
126+ $newRgn{DLYArea} = {
127+ X => $rect[0] + $rect[2]/2,
128+ Y => $rect[1] + $rect[3]/2,
129+ W => $rect[2],
130+ H => $rect[3],
131+ } if @rect == 4;
132+ }
133+ push @newRgns, \%newRgn;
134+ }
135+ return {
136+ AppliedToDimensions => { W => $val[1], H => $val[2], Unit => 'pixel' },
137+ RegionList => \@newRgns,
138+ };
139+ },
140+ },
141+ # create an ACDSee RegionInfo structure from an IPTC ImageRegion list
142+ IPTCRegion2ACDSeeRegion => {
143+ Require => {
144+ 0 => 'ImageRegion',
145+ 1 => 'ImageWidth',
146+ 2 => 'ImageHeight',
147+ },
148+ ValueConv => q{
149+ my ($rgn, @newRgns);
150+ my $rgns = ref $val[0] eq 'ARRAY' ? $val[0] : [ $val[0] ];
151+ foreach $rgn (@$rgns) {
152+ my %newRgn = ( Type => 'Face' );
153+ if ($$rgn{RegionBoundary} and $$rgn{RegionBoundary}{RbShape} eq 'rectangle') {
154+ my @rect = @{$$rgn{RegionBoundary}}{'RbX','RbY','RbW','RbH'};
155+ if ($$rgn{RegionBoundary}{RbUnit} eq 'pixel') {
156+ $rect[0] /= $val[1], $rect[2] /= $val[1];
157+ $rect[1] /= $val[2]; $rect[3] /= $val[2];
158+ }
159+ $newRgn{'DLYArea'} = {
160+ X => $rect[0] + $rect[2]/2,
161+ Y => $rect[1] + $rect[3]/2,
162+ W => $rect[2],
163+ H => $rect[3],
164+ };
165+ } else {
166+ next unless defined $$rgn{Name};
167+ }
168+ $newRgn{Name} = $$rgn{Name} if defined $$rgn{Name};
169+ push @newRgns, \%newRgn;
170+ }
171+ return {
172+ AppliedToDimensions => { 'W' => $val[1], 'H' => $val[2], 'Unit' => 'pixel' },
173+ RegionList => \@newRgns,
174+ };
175+ },
176+ },
177+
178+ # create an MWG RegionInfo structure from an IPTC ImageRegion list
179+ MWGRegion2ACDSeeRegion => {
180+ Require => {
181+ 0 => 'RegionInfo',
182+ 1 => 'ImageWidth',
183+ 2 => 'ImageHeight',
184+ },
185+ ValueConv => q{
186+ my ($rgn, @newRgns);
187+ my %newRgn;
188+ foreach $rgn (@{$val[0]{RegionList}}) {
189+ next unless $$rgn{Area} or defined $$rgn{Name};
190+ my %newRgn;
191+ if ($$rgn{Area}) {
192+ $newRgn{'DLYArea'} = {
193+ 'X' => $$rgn{Area}{'X'},
194+ 'Y' => $$rgn{Area}{'Y'},
195+ 'W' => $$rgn{Area}{'W'},
196+ 'H' => $$rgn{Area}{'H'},
197+ };
198+ };
199+ $newRgn{Name} = $$rgn{Name} if defined $$rgn{Name};
200+ $newRgn{'Type'} = $$rgn{'Type'} if defined $$rgn{'Type'};
201+ push @newRgns, \%newRgn;
202+ }
203+ return {
204+ 'AppliedToDimensions' => $val[0]{'AppliedToDimensions'},
205+ RegionList => \@newRgns,
206+ }
207+ },
208+ },
209+ ####
210+ },
49211);
50212
51213%Image::ExifTool::UserDefined::ACDSeeRegions = (
@@ -54,18 +216,43 @@ my %sACDSeeRegionStruct = (
54216 WRITABLE => 'string', # (default to string-type tags)
55217 Regions => {
56218 Name => 'RegionInfoACDSee',
219+ FlatName => 'ACDSee',
57220 # the "Struct" entry defines the structure fields
58221 Struct => {
59222 # optional structure name (used for warning messages only)
60223 STRUCT_NAME => 'ACDSee RegionInfo',
61224 RegionList => {
225+ FlatName => 'Region',
62226 Struct => \%sACDSeeRegionStruct,
63227 List => 'Bag',
64228 },
65- AppliedToDimensions => { Struct => \%sACDSeeDimensions },
229+ AppliedToDimensions => {
230+ FlatName => 'RegionAppliedToDimensions',Struct => \%sACDSeeDimensions },
66231 },
67232 },
68233);
69234
235+ # Shortcuts to old names added so as not to break previously used commands
236+ %Image::ExifTool::UserDefined::Shortcuts = (
237+ RegionInfoACDSeeAppliedToDimensionsH => 'ACDSeeRegionAppliedToDimensionsH',
238+ RegionInfoACDSeeAppliedToDimensionsUnit => 'ACDSeeRegionAppliedToDimensionsUnit',
239+ RegionInfoACDSeeAppliedToDimensionsW => 'ACDSeeRegionAppliedToDimensionsW',
240+ RegionInfoACDSeeRegionListDLYAreaH => 'ACDSeeRegionDLYAreaH',
241+ RegionInfoACDSeeRegionListDLYAreaW => 'ACDSeeRegionDLYAreaW',
242+ RegionInfoACDSeeRegionListDLYAreaX => 'ACDSeeRegionDLYAreaX',
243+ RegionInfoACDSeeRegionListDLYAreaY => 'ACDSeeRegionDLYAreaY',
244+ RegionInfoACDSeeRegionListALGAreaH => 'ACDSeeRegionALGAreaH',
245+ RegionInfoACDSeeRegionListALGAreaW => 'ACDSeeRegionALGAreaW',
246+ RegionInfoACDSeeRegionListALGAreaX => 'ACDSeeRegionALGAreaX',
247+ RegionInfoACDSeeRegionListALGAreaY => 'ACDSeeRegionALGAreaY',
248+ RegionInfoACDSeeRegionListName => 'ACDSeeRegionName',
249+ RegionInfoACDSeeRegionListType => 'ACDSeeRegionType',
250+ RegionInfoACDSeeRegionListNameAssignType => 'ACDSeeRegionNameAssignType',
251+ );
252+
253+ # Forced -struct option during debugging
254+ #%Image::ExifTool::UserDefined::Options = (
255+ # Struct => 1,
256+ #);
70257#------------------------------------------------------------------------------
712581; #end
0 commit comments