Hi there, I've searched a fair chunk of forum history, read as much as I can and experimented as much as possible and I'm stuck :)
I'm trying to set the MakerNotes to my own custom binary data. Is this possible with ExifTool? If so, how can I do it? I understand I have to copy it as a block, but how can I do this? Can I block import from a file, for example? I cannot find a command line action for this.
Thank you!!
Hi Josh,
The only way to do this is to override the ExifTool MakerNotes with a user-defined tag and a config file like this:
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Exif::Main' => {
0x927c => {
Name => 'MyMakerNotes',
Writable => 'undef',
Binary => 1,
},
},
);
1; # end
See the sample config file (https://exiftool.org/config.html) for instructions on using a config file.
- Phil
Hi Phil,
Thank you so much for your response!
I have created the following .ExifTool_config file:
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Exif::Main' => {
0x927c => {
Name => 'MyMakerNotes',
Writable => 'undef',
Binary => 1,
},
},
);
1; #end
And I am trying to run it like this:
exiftool -MyMakerNotes= image.jpg
But the output says:
0 image files updated
1 image files unchanged
Where do I place the binary I'd like to use? Is it the Binary => 1,
part of the config file? Currently I have a small file I'd like to embed in the MakerNotes section.
Many thanks again,
Josh
Hi Josh,
Quote from: joshcomley on January 20, 2014, 10:38:15 AM
exiftool -MyMakerNotes= image.jpg
But the output says:
0 image files updated
1 image files unchanged
This command deletes the maker notes. It will give this message if they didn't exist.
QuoteWhere do I place the binary I'd like to use?
For example, to get the maker notes from file "DATA.BIN", do this:
exiftool "-mymakernotes<=DATA.BIN" file.jpg- Phil
Thanks again Phil, that works perfectly!
I just tried on a bunch of files. It worked for some but some exceed 64kb in size; is there anything I can do (save making it smaller, which is theoretically impossible at the moment)?
In my reading I learned about the ability to exceed 64kb if the data spans multiple segments but I couldn't find any real explanations of how to achieve this or any hint of pseudocode to adapt.
I noticed here:
http://www.exiftool.org/writing.html#JPEG (http://www.exiftool.org/writing.html#JPEG)
You mention
QuoteThis multi-segment information is handled properly by ExifTool.
:)
So is there a way I can split my file up or do some magic to achieve this?
Many thanks again, I really appreciate ExifTool and your excellent help.
Josh
Hi Josh,
The EXIF specification limits EXIF data to a single segment in JPEG images, so it can not exceed 64 kB. (And the MakerNotes you are writing are contained in the EXIF.) If you want to store more, you need to go to something other than EXIF.
- Phil
Thanks Phil, I was worried that would be the case.
Do you have a suggestion of what to Google?
Are you talking about APP2, for example?
Hi Josh,
If you are talking about the ICC_Profile APP2 information, then no.
The XMP APP1 would be the place, except the XMP doesn't support binary data directly, so it would need to be encoded (probably Base64). For example, you could hide it in XMP:ThumbnailImage, which does the Base64 encoding.
There really aren't any extensible alternatives for storing >64kB binary data directly in a JPEG image.
You could put it in a MIE trailer, but only ExifTool understands those, so it would be of limited use.
- Phil
Ah, yes, I can encode it to Base64 no problem.
XMP:ThumbnailImage seems like a good solution.
Interestingly, I've tried injecting >64kb in the MakerNote field (actually base 64 encoded) using a few other mechanisms, one which I brute force the content in there regardless of size.
Sometimes the data is >100kb and it resulted in a functioning JPEG but with a "Bad MakerNote" section reported if I let ExifTool analyse it.
But crucially the some of the JPEGs with this large MakerNote data would still render fine in all viewers. I just wish I could make it consistent across all JPEG/MakerNote combinations; I'm not sure why some work and some don't.
You must have split the EXIF into multiple JPEG segments, which is not allowed by the standard, and ExifTool can not be used to read this.
But XMP sounds like the way to go. ExifTool will do the Base64 encoding for you. If you use XMP:ThumbnailImage, it is done already. If you create a user-defined tag, then add these conversions:
ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
- Phil
Hi Phil,
I've been experimenting with the config file and so on and I've got something working with one problem.
Here is my config file:
%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::xmp' => {
JoshTag => {
SubDirectory => {
TagTable => 'Image::ExifTool::UserDefined::JoshTag',
# (see the definition of this table below)
},
Name => 'JoshTag',
Writable => 'string',
},
},
);
%Image::ExifTool::UserDefined::JoshTag = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-JoshTag', 2 => 'Image' },
WRITABLE => 'string',
# example structured XMP tag
NewXMPJoshTagStruct => {
# the "Struct" entry defines the structure fields
Struct => {
},
},
);
1; #end
I actually do the base 64 encoding myself outside and then use:
exiftool "-JoshTag<=base64.txt" image.jpg
It works, but roughly every 64kb is split up by something that looks like this:
<?xpacket end='w'?>[b]ÿáÿÿhttp://ns.adobe.com/xmp/extension/ 3AFF02DE3FEB5AF9C895191EF2F39234 ¦$ [/b]<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 9.47'>
Is there anyway to prevent this or does XMP get split up into 64kb chunks like this? I will be parsing the XMP out of the jpeg completely manually so I am trying to work out how to read the string value without this being in the way. I could parse out the value of the namespace above, but I've tried that and what is inbetween the xpacket end tag and <x:xmpmeta does not exactly match what appears in the string.
Another option I have is to have separate custom tags (JoshTag1, JoshTag2 etc.) and split it up into 60kb chunks, but this seems even more hacky than what I'm already doing :)
Can I tell ExifTool to not place this marker in? Or perhaps specify what the marker should be so I can predict it?
Many thanks again and again!!
Josh
Anything stored inside the JPEG must be spit into maximum 64kB segments. If you don't want it to be split, the only option is to put it in a trailer. In the most simple form, you can do this:
cat data.bin >> image.jpg
(assuming you are running Mac or Linux this will work. In Windows, you will need some other technique to concatenate the two files.)
By the way, your user-defined tag definition is confused. You are writing it as a simple tag in the xmp namespace, so the user-defined namespace and structure are superfluous, and this will do the same thing:
%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::xmp' => {
JoshTag => { },
},
);
1; # end
- Phil
Phil just wanted to say thank you so much for your help, it's vitally appreciated. If I make millions I'll send something your way!!
Your tool is fantastic and your support somehow even better.