photostructure / exiftool-vendored.js Goto Github PK
View Code? Open in Web Editor NEWFast, cross-platform Node.js access to ExifTool
Home Page: https://photostructure.github.io/exiftool-vendored.js/
License: MIT License
Fast, cross-platform Node.js access to ExifTool
Home Page: https://photostructure.github.io/exiftool-vendored.js/
License: MIT License
I was able to read the EXIF data successfully!
I am still a bit confused how to overwrite.
Thank you very much!
This is what I have for the read part:
fs.readdir(dir, function (err, files) {
files.forEach(function (file) {
exiftool
.read(dir+'/'+file)
.then((tags /*: Tags */) => {
console.log(`【${file}】Orientation: ${tags.Orientation}`);
});
});
Hi Thanks for your great Job
can you share me, how to using DefaultExifToolOptions ?
e.g to update taskTimeoutMillis: 2000 -> taskTimeoutMillis: 5000
thanks
Hi there,
I can't seem to be able to write to list tags. See https://www.sno.phy.queensu.ca/~phil/exiftool/faq.html#Q17
When I do something along the lines of
exiftool.write({ SupplementalCategories: [1,2,3] })
The resultant metadata is
<photoshop:SupplementalCategories>
<rdf:Bag>
<rdf:li>1,2,3</rdf:li>
</rdf:Bag>
</photoshop:SupplementalCategories>
</rdf:Description>
wheras it should be:
<photoshop:SupplementalCategories>
<rdf:Bag>
<rdf:li>1</rdf:li>
<rdf:li>2</rdf:li>
<rdf:li>3</rdf:li>
</rdf:Bag>
</photoshop:SupplementalCategories>
</rdf:Description>
Exiftool automatically concatenates the list version from above and thus reports on both the same as follows:
Supplemental Categories : 1,2,3
Thanks for your help.
yarn add exiftool-vendored
node index.js
OK
yarn add anything-else
node index.js
Error: Cannot find module 'exiftool-vendored.pl'
at Function.Module._resolveFilename (module.js:470:15)
at Function.Module._load (module.js:418:25)
at Module.require (module.js:498:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/srv/nodejs/test-exiftool/node_modules/exiftool-vendored/dist/ExifTool.js:17:20)
at Module._compile (module.js:571:32)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
index.js
includes only import of exiftool-vendored
module
Works ok only on clean install or if exiftool-vendored.pl
explicitly added as a package dependency.
This does not cause much inconvenience in a case of exiftool-vendored
is a direct dependency. But it is not so if there are intermediate dependencies.
For example module-a -> module-b -> exiftool-vendored
. Whenever a module-a
adds a new dependency, mobule-b
will throw an error.
Are below essentially the same in terms of invocation? Essentially in both cases A.
and B.
exiftool-vendored
is actually run in -stay_open
mode and the only difference is ability to set custom args
in A.
with exiftoolArgs
:
A.
const ExifTool = require('exiftool-vendored').ExifTool;
const exiftool = new ExifTool({exiftoolArgs: ['-stay_open', 'True', '-@', '-']});
(async () => {
const meta = await exiftool.read('path/to/image.jpg');
exiftool.end();
})();
B.
const exiftool = require('exiftool-vendored').exiftool
(async () => {
const meta = await exiftool.read('path/to/image.jpg');
exiftool.end();
})();
Or does -stay_open
have to be explicitly set as per A.
?
Hi there 🙂
First I'd like to thanks @mceachen & contributors of this lib which is great 👍
Then today I experienced a weird problem, here is the context :
exiftool.read(filepath) .then(tags => ...)
exiftool.write(filepath, { AllDates: newDateStr })
This script worked on multiple files before failing on a particular file.
The first problem here is that all my code is wrapped with catch and no error popped out, it just stops code execution after exiftool.write
and never come into the then
or catch
I managed to find the problem by using ExifTool via command line: Error reading ThumbnailImage data
So this is the error that should have appeared before and wasn't thrown.
Then I managed to found on the ExifTool author faq http://owl.phy.queensu.ca/~phil/exiftool/faq.html#Q20 that you can repair file exif with :
exiftool -all= -tagsfromfile @ -all:all -unsafe -icc_profile bad-file.jpg
So I would suggest implementing this repair ability as a method of this lib or as an option when writing :)
What do you think?
MacOS 10.13.6 High Sierra
Reading IPTC tags from a .dng file and the hyphenated ones don't work
Code fragment -
var reado =
`Make: ${tags.Make},
Model: ${tags.Model},
Sub-location: ${tags.Sub-location},
City: ${tags.City},
Province-State: ${tags.Province-State},
Country-PrimaryLocationName: ${tags.Country-PrimaryLocationName},
UserComment: ${tags.UserComment}`;
console.log('READO ', reado);
})
.catch(err => console.error("Something terrible happened: ", err))
eg: typical error is -
Something terrible happened: ReferenceError: State is not defined at exiftool.read.then (app.js:730) etc
Sub-location - FAIL
City - OK
Province-State - FAIL
Country-PrimaryLocationName - FAIL
Cheers,
Blane
I have a CreateDate
that looks like this:
CreateDate:
ExifDateTime {
year: 2019,
month: 3,
day: 8,
hour: 14,
minute: 24,
second: 54,
millisecond: 0,
tzoffsetMinutes: -480 }
When running toDateTime()
on the ExifDateTime
I am getting:
Error: Invalid unit tzoffsetMinutes
at normalizeUnit (/Users/reinhard/Work/Open Source/dedupe-by-exif-date/node_modules/luxon/build/node/luxon.js:4954:26)
at normalizeObject (/Users/reinhard/Work/Open Source/dedupe-by-exif-date/node_modules/luxon/build/node/luxon.js:264:18)
at Function.fromObject (/Users/reinhard/Work/Open Source/dedupe-by-exif-date/node_modules/luxon/build/node/luxon.js:5273:24)
...
My goal was to convert the date to a timestamp via the DateTime
instance. Here's my yarn.lock for any versions of things you might want to know: http://yo.bkwld.com/09c026aa1698.
Thanks!
Is your feature request related to a problem? Please describe.
First of all, congratulations! I'm running this project on a migration script for my company and it's helping us to extract exifData from 300k+ images.
Problem: It's running on a aws batch script. It started to just stop, exiting with an 0 code and I though that it might be related to the cpu (I was only using 2 vcpus), memory and stuff related to machine limitation. Spent some time improving the script and running it on a docker container with limited resources to replicate the environment and nothing changed.
In the end, the problem was that the image was too big and would take more than 10 seconds to extract its exifData.
Describe the solution you'd like
Took a deeper dive on your readme today and saw the error handling session... I think it could have a code sample and some kind of highlight to warn the users to use it to get proper error logs. In my case, I had to throw the error on the node script so the aws batch could set it as failed instead of success. Also had to increase the timeout with the taskTimeoutMillis
param.
I think this project should have some kind of warning to tell users that are dealing with bigger images that they probably would like to increase the task timeout. Also, warning them about the error logging and creating a code sample showing how to handle errors would be good.
I can open a PR if you guys are too busy.
In the case of modifying 10,000+ photos: Do I have to manually create a throttling process to only process 1 photo with exiftool.write
at the time and await each promise? Or does exiftool-vendored have auto queueing during exiftool.write
on a large amount of photos?
Since exiftool-vendored has maxprocs
to help the CPU from being overloaded with Parallelism, I'm wondering how to correctly use exiftool-vendored.
I have a complicated process (where I need to look at about 500 folders in order, check the date of the first photo of the previous folder and apply changes depending on if this date is the same as the first photo of the next folder.)
Also, since I am only a NodeJS and JavaScript developer I was hoping to use this library instead of the pearl CLI.
In my case I am planning to write a script that does these things synchronously:
exiftool.write
) to photos in the target folder (depending on the result of the checking in prev step)I don't anticipate a work overload since each folder doesn't have that many photos.
However, when there is a folder with a very large amount of photos to be modified in the above step 2, and my CPU is pushed to the max limit of the exiftool-vendored:
exiftool.write
calls I made and wait until the CPU has regained some breathing space?exiftool.write
at the time and await each modification?Building an app with electron and react and keep getting this issue when using exiftool-vendored.
I have read the previous post on the matter and tried to add exiftool-vendored.pl to my dependencies manually and this only generates the following error
My package.json
{ "name": "photo-op", "version": "0.1.0", "private": true, "dependencies": { "@babel/register": "^7.4.0", "@material-ui/core": "^3.9.3", "@material-ui/icons": "^3.0.2", "exiftool-vendored": "^8.8.0", "react": "^16.8.6", "react-dom": "^16.8.6", "react-redux": "^7.0.2", "react-router": "^5.0.0", "react-router-dom": "^5.0.0", "react-scripts": "2.1.8", "recursive-readdir": "^2.2.2", "redux": "^4.0.1", "styled-components": "^4.2.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "electron": "electron ./src/main.js" }, "eslintConfig": { "extends": "react-app" }, "browserslist": [ ">0.2%", "not dead", "not ie <= 11", "not op_mini all" ], "devDependencies": { "electron": "^4.1.4" } }
Extracted from #23
Tracks implementation of
/**
* Attempt to fix metadata problems in JPEG images by deleting all metadata and rebuilding from
* scratch. After repairing an image you should be able to write to it without errors, but some
* metadata from the original image may be lost in the process.
*
* This should only be applied as a last resort to images whose metadata is not readable via
* {@link .read()}.
*
* @param {string} inputFile the path to the problematic image
* @param {string} outputFile the path to write the repaired image
* @param {boolean} allowMakerNoteRepair if there are problems with MakerNote tags, allow
* ExifTool to apply heuristics to recover corrupt tags. See exiftool's `-F` flag.
* @return {Promise<void>} resolved when outputFile has been written.
*/
rewriteAllTags(inputFile: string, outputFile: string, allowMakerNoteRepair: boolean = false)
Hi,
Thank you for this great tool.
Ran into this issue where running
exiftool ExifTool.jpg
gives 'Original Image Width/Height' to be 16. (ExifTool.jpg is a test image in the original exiftool distribution (Image-ExifTool-11.06.tar.gz) under t/images directory)
When running through exiftool-vendored getting 'undefined' for OriginalImageWidth/Height
with
ExifDateTime {
year: 1907,
month: 1,
day: 1,
hour: 0,
minute: 0,
second: 0,
millisecond: 0,
tzoffsetMinutes: 0,
rawValue: '1907:01:01 00:00:00+00:00' }
code:
console.log (meta.DateTimeCreated) //result : 1907-01-01T00:00:00.000Z ok
console.log (meta.DateTimeCreated.toString()) //result : 1907-01-01T00:00:00.000Z ok
console.log (moment(meta.DateTimeCreated).format('DD/MM/YYYY HH:mm:ss')) //result : 01/02/1907 00:00:00 not ok
really strange!!
I actually get an error, coming from a corrupted jpeg .
The problem is, I didn't find the way to catch the way to "catch" the error, and not display it to the console .
So, I get this error (on the console) :
BatchProcess(9328).onError() { source: 'stderr.data',
task:
'-AllDates=2018-08-14T12:26:58.000\n-overwrite_original\n-charset\nfilename=utf8\n-codedcharacterset=utf8\nC:\\Users\\thib3\\repos\\timer-correct\\photos\\test\\AFS2018-223.JPG\n-ignoreMinorErrors\n-execute\n',
error:
Error: stderr.data: Bad InteropIFD offset for InteropIndex - C:/Users/thib3/repos/timer-correct/photos/test/AFS2018-223.JPG
at BatchProcess.<anonymous> (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:312:25)
at step (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:32:23)
at Object.next (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:13:53)
at C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:7:71
at new Promise (<anonymous>)
at __awaiter (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:3:12)
at BatchProcess.onError (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:306:16)
at Socket.<anonymous> (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:81:26)
at Socket.emit (events.js:182:13)
at addChunk (_stream_readable.js:283:12) }
Task.reject() { cmd:
'-AllDates=2018-08-14T12:26:58.000\n-overwrite_original\n-charset\nfilename=utf8\n-codedcharacterset=utf8\nC:\\Users\\thib3\\repos\\timer-correct\\photos\\test\\AFS2018-223.JPG\n-ignoreMinorErrors\n-execute\n',
error:
Bad InteropIFD offset for InteropIndex - C:/Users/thib3/repos/timer-correct/photos/test/AFS2018-223.JPG
at Socket.<anonymous> (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:81:49)
at Socket.emit (events.js:182:13)
at addChunk (_stream_readable.js:283:12)
at readableAddChunk (_stream_readable.js:264:11)
at Socket.Readable.push (_stream_readable.js:219:10)
at Pipe.onread (net.js:635:20) }
file .\1532926361.jpg was corrected and moved to C:\Users\thib3\repos\timer-correct\photos\test\1532925761.jpg (3/4)
BatchProcess(12396).onError() { source: 'stderr.data',
task:
'-AllDates=2018-08-14T12:26:58.000\n-overwrite_original\n-charset\nfilename=utf8\n-codedcharacterset=utf8\nC:\\Users\\thib3\\repos\\timer-correct\\photos\\test\\AFS2018-223.JPG\n-ignoreMinorErrors\n-execute\n',
error:
Error: stderr.data: Bad InteropIFD offset for InteropIndex - C:/Users/thib3/repos/timer-correct/photos/test/AFS2018-223.JPG
at BatchProcess.<anonymous> (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:312:25)
at step (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:32:23)
at Object.next (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:13:53)
at C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:7:71
at new Promise (<anonymous>)
at __awaiter (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:3:12)
at BatchProcess.onError (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:306:16)
at Socket.<anonymous> (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:81:26)
at Socket.emit (events.js:182:13)
at addChunk (_stream_readable.js:283:12) }
Task.reject() { cmd:
'-AllDates=2018-08-14T12:26:58.000\n-overwrite_original\n-charset\nfilename=utf8\n-codedcharacterset=utf8\nC:\\Users\\thib3\\repos\\timer-correct\\photos\\test\\AFS2018-223.JPG\n-ignoreMinorErrors\n-execute\n',
error:
Bad InteropIFD offset for InteropIndex - C:/Users/thib3/repos/timer-correct/photos/test/AFS2018-223.JPG
at Socket.<anonymous> (C:\Users\thib3\repos\timer-correct\node_modules\batch-cluster\dist\BatchProcess.js:81:49)
at Socket.emit (events.js:182:13)
at addChunk (_stream_readable.js:283:12)
at readableAddChunk (_stream_readable.js:264:11)
at Socket.Readable.push (_stream_readable.js:219:10)
at Pipe.onread (net.js:635:20) }
I tried some options :
let currExiftool = new ExifTool(Object.assign(exiftool.options, {
exiftoolArgs : ["overwrite_original"],
minorErrorsRegExp: /InteropIFD/gi //this doesn't resolve the problem
}));
//this debugger is not called, so I think it's not called
currExiftool.rejectTaskOnStderr = () => {debugger; return true};
await currExiftool.write(file, {AllDates: DateTimeOriginal.toString()}, ["-overwrite_original"]).catch(err=>console.log("catched"));
Doesn't throw error, but log catched
after the console.log .
So my question is :
How to get this error ? (not in the console), or how to hide this error please ?
Dear @mceachen
I'm really sorry to make another post, and I don't try to make you do free work for me.
In fact, if you have a paypal account or a bitcoin address, I'd be happy to tip you!!
You see, I'm having a problem understanding how to use -stay_open
.
I read the official documentation about -stay_open but I'm afraid, it's really difficult to understand...
I have about 10,000 image paths that I want to edit with exiftool. I'm doing it like so:
imgPaths.forEach(imgPath => {
// get the date from a json file
let parentFolder = imgPath.split('/')[imgPath.split('/').length-2]
let comment = folderInfo['keywords']
let date = folderInfo['date']+' 12:00:00.000+01:00'
// do the exiftool write
exiftool
.write(imgPath, {
'MDItemFSCreationDate': date,
'AllDates': date,
})
.then(suc => success(suc)).catch(err => catchErr(err))
But every time it hangs around 3000 images, so I think the memory is up. It's so bad I have to restart the computer after...
Do you have any advice on how to add -stay_open
to this? I tried it as a third argument to the write function, but it didn't work.
Feel free to delete this thread if you want. I don't want to trouble you too much...
I'm so sorry, I don't know who else to ask.
Hi, is there anything about adding custom tag definitions?
I have a set of custom XMP tags I use for catagorising images, is there a way to add their definitions so I can read them?
If so:
Could the documentation be updated to make this feature's use clearer if it's easy? and could you tell me how to do it?
If not:
I would like to see this feature implemented somehow. It might be a bit outside my wheelhouse, so I might not it myself.
Hello there @mceachen,
Excellent package, thanks a lot. I need to get this working with a multi-platform Electron Builder build, and am having no luck so far.
You mentioned in a previous issue that you had managed to get this working using a few tricks:
It took me a while to get the right combination of electron packaging (I am using electron-builder ), webpack config, asar exclusions, and __dirname workarounds to make everything work cross-platform.
Would you mind sharing exactly what you did?
Thanks again.
I'm known to require a fairly complicated setup to organise my photo's, but I actually worked hard until I had a setup that's really straight forward and easy to reason about.
I just go through each folder synchronously and do each exiftool write also synchronously.
Meaning I await
every single write.
Yet still my process gets cut off at around 30 folders (as seen in the screenshot below) but without any error!
Could you comment on my code how I should debug the exiftool.write
, because I think I'm failing to log errors somewhere in the code.
First I wrapped exiftool.write
into a writeDate
function:
const { ExifTool } = require('exiftool-vendored')
const exiftool = new ExifTool()
export default function (path, date) {
return new Promise((resolve, reject) => {
exiftool
.write(path, {
'MDItemFSCreationDate': date,
'AllDates': date
})
.then(resolve).catch(reject)
})
}
Then I do my process:
const start = async () => {
await asyncForEach(foldersByDate, async (date) => {
console.log('=======', date, '========')
const photoPaths = getFileList(ROOTPATH + '/' + date, true)
await asyncForEach(photoPaths, async (photoPath) => {
if (!photoPath.includes('.jpg')) return
const photoName = photoPath.split('/').slice(-1)[0]
const time = photoName.split(' ').slice(-1)[0].replace('.jpg', '').replace(/\./g, ':')
await writeDate(photoPath, `${date}T${time}`).catch(console.error)
// the catch.(console.error) should trigger on anything that goes wrong
})
})
console.log('Finished!') // never reaches here
}
start()
Here down below you see the terminal console not showing any errors, but stopping mysteriously...
Any advice is much appreciated, and I'm sorry to always come to you for help!!!!
(PS, the asyncForEach
function is inspired from this Medium post and works perfectly. The folders all have a few seconds in between them as they are logged in the console.)
From Readme:
Feel free to review the ExifTool constructor parameters and override default values where appropriate if the defaults wont' work for you
The url to ExifTool constructor parameters is broken.
Having to manage and deal with temporary files all over the place (not to mention the *_original files) is kind of a pain. Being able to work with node streams directly would make this much easier.
For example, exiftool.read() could take a stream. Functions like extractPreview(filepath/inputstream) could take 1 argument (file or stream) and then process the output by either having .write(newfilepath) or .stream().pipe(outputstream). The gm package has a really nice way of handling this (https://github.com/aheckmann/gm)
Is there any way to work with streams currently or is it purely a feature that is not implemented yet? And if so, are there any plans to support streams in the future?
I have installed laravel-mix to have a simple webpack wrapper.
I have added this script in package.json
: "dev": "node node_modules/cross-env/dist/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
When I try to run npm run dev
, the only thing it should do is compile my JS file to include the top two lines of my js file:
let fs = require('fs');
import { exiftool } from "exiftool-vendored";
But I get the following error:
Failed to compile with 3 errors
These dependencies were not found:
* fs in ./dev/run.js, ./~/exiftool-vendored/dist/exiftool_process.js
* child_process in ./~/exiftool-vendored/dist/exiftool_process.js
To install them, you can run: npm install --save fs child_process
Note, this is on MacOS using exiftool v10.25
Exiftool's 'File Modification Date/Time' field appears to be the file's mtime or birthtime (inspected via lstat) - which is what I am expecting.
This exiftool package is returning what looks like atime or ctime for FileModifyDate.
Regardless of where it is derived, should these fields match?
EDIT: this was actually my issue - MacOS was preserving the birthtime when moved, but unix mv modifies it.
It would be really nice to be able to use a remote URLs instead of a local path so that nothing is persisted on the file system.
I'm not that into the source code, TypeScript and ExifTool to make a PR however.
Is your feature request related to a problem? Please describe.
Ironically this library has the best JS wrapper API around Exiftool and I’d love to use it with pre-installed exiftool
.
Describe the solution you'd like
The ability to install the library without also installing a vendored dependency of exiftool.
Additional context
I’m running this in Lambda and after attempting the solutions proposed in #53 with no luck I ended up creating my own Lambda layer. I can’t use this library now though because it expects exiftool-vendored.pl to be there.
At the moment depending on RAW file processed specific previews are available for extraction. Running exiftool -preview:all nikon_d850.nef
we get 4x previous we can choose from:
Jpg From Raw -> exiftool.extractJpgFromRaw()
Other Image -> ?
Preview Image -> exiftool.extractPreview()
Thumbnail TIFF -> exiftool.extractThumbnail()
In some cases Preview is reported as PreviewTIFF
and not as PreviewImage
as per Hasselblad RAW file which seems to be impossible to extract via build in extractPreview()
option but can be extracted directly with:
exiftool -PreviewTIFF -b B0000994.3FR > B0000994.JPG
It would be good to support this via extractPreview
.
Hello,
I am having trouble with the package. This is the issue I am getting when trying to read exif data:
TypeError: gps.toDate is not a function
at TagsTask.extractTzoffset (E:\photos\node_modules\exiftool-vendored\dist\tags_task.js:64:41)
at TagsTask.parseTags (E:\photos\node_modules\exiftool-vendored\dist\tags_task.js:72:14)
at TagsTask.parse (E:\photos\node_modules\exiftool-vendored\dist\tags_task.js:46:21)
at TagsTask.Task.onData (E:\photos\node_modules\exiftool-vendored\dist\task.js:26:31)
at ExifToolProcess.onData (E:\photos\node_modules\exiftool-vendored\dist\exiftool_process.js:137:22)
at Socket.<anonymous> (E:\photos\node_modules\exiftool-vendored\dist\exiftool_process.js:40:65)
at emitOne (events.js:101:20)
at Socket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:176:18)
at Socket.Readable.push (_stream_readable.js:134:10)
I am on node 6.10.0.
Thanks a lot,
Christian
... that i love You. You save my day.
Thank You for that module, i will try to help if will be able to.
You can remove this comment if You want.
I tried to write { AllDates: "some iso date" }
, but appearently WriteTags
does not contain AllDates
. The TypeScript-compiler fails on this
new ExifTool().write(file, { AllDates: '2017-07-27T10:28:35.000Z' })
exiftool can not be spawned in aws lambda environment, getting below error stack:
2019-07-18T14:45:17.836Z 288aa49b-491d-5394-a451-f131c125cf30 Error: spawn /var/task/node_modules/exiftool-vendored.pl/bin/exiftool ENOENT
at _errnoException (util.js:1022:11)
at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
at onErrorNT (internal/child_process.js:372:16)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickDomainCallback (internal/process/next_tick.js:218:9)
Using lambci/lambda:nodejs8.10 image (https://github.com/lambci/docker-lambda) the problem can be reproduced.
The error happens when initializing the below Metadata class
export default class Metadata {
private static tool: ExifTool = Metadata.initTool();
public static tmpDirectory = `${tmpdir()}/metadata`;
private static initTool(): ExifTool {
logger.debug("initializing exiftool...");
const tool = new ExifTool();
tool.version().then(version => logger.info(`ExifTool version ${version}`));
return tool;
}
Thanks for the great tool
Dear @mceachen ,
Can I use your NPM exiftool directly from the terminal in macOS?
How would select a folder on my computer and set the taken datetime for all photos inside to e.g. 1990-01-30?
It would be great if I could see a sample!
(I know it's originally a perl program, but I thought to try yours, because I only know javascript. I'm not sure if I should run it through my browser or in the command line, and how to target files on my computer though!)
When file path have non-english words, the exifTool.read()
throw error like that:
stderr.data: File not found: G:/xxx/xxx/test_images/中文資料夾/2185_hodesti_00_p_1024x768.jpg
Hi there,
First of all thanks for your work on exiftool-vendored, its a great library and a huge help to me!
So I'm using Electron and in development exiftool-vendored is working perfectly. However when I build for production and attempt to write to a file I'm getting the following errors in the console:
I'm using exiftool-vendored version 4.18.1
and running on Ubuntu
Cheers
Describe the bug
When I try to write tags to a non-existing file, the promise returned by exiftool.write
does not get rejected. Instead, the whole process seems to be killed.
To Reproduce
The following code tries to write a tag to a file abc.jpg
that we assume not to exist.
const Exiftool = require("exiftool-vendored").ExifTool;
const exiftool = new Exiftool({});
(async () => {
try {
console.log("WRITING");
await exiftool
.write("abc.jpg", { AllDates: "2003-03-03-03-03-03" })
console.log("DONE");
} catch (err) {
console.error("ERROR:", err);
} finally {
console.log("FINALLY");
}
})();
Expected behavior
The promise returned by exiftool.write
should be rejected, because the file abc.jpg
does not exist.
The output should be
WRITING
ERROR: <something about the missing file>
FINALLY
The actual output is:
WRITING
which indicates that neither the catch-block, nor the line after the .write()
, nor the finally block are executed.
Environment (please complete the following information):
Is your feature request related to a problem? Please describe.
I'm looking to extract the EXIF tags from a number of images and write the tags for each image into a separate XML file.
Describe the solution you'd like
A separate API like exiftool.readRaw(path[, options])
that allows for flags like -X
to return just the RAW (or in this case, XML) output as a string/Buffer that could then be interacted with.
Describe alternatives you've considered
exiftool-vendored.js
parsing the JSON output, andexiftool.pl
hasexiftool-vendored.js
performance and handling of processes.exiftool.pl
directly, either through exiftool-vendored.pl
or a direct install, though I'd like to avoid re-inventing this module, and for the same reasons as above.From your docs:
Always Beware: Timezones
If you edit a timestamp tag, realize that the difference between the changed timestamp tag and the GPS value is used by exiftool-vendored to infer the timezone.
In other words, if you only edit the CreateDate and don't edit the GPS timestamps, your timezone will either be incorrect or missing.
Is it possible to elaborate on which GPS timestamps
we need to edit?
The reason being: I have a bunch of scanned photos I'm adding the date taken to manually.
At first I thought of just writing the dates as mentioned: exiftool.write("path/to/file.jpg", { AllDates: "2016-02-06T16:56:00" });
But after reading this I got a bit scared that wouldn't be enough.
Here is code snippet to create an instance of exif tool. From this command, am expecting only format tag should be returned from the response. However, am getting all tags.
var exiftool_vendored = require("exiftool-vendored")
//const exifTool = new exiftool_vendored.ExifTool()
const exifTool = new exiftool_vendored.ExifTool({ exiftoolArgs: ["-stay_open", "True","-format","-@", "-"] });
console.log(exifTool.options)
However, am getting the response using Exiftool command:
Exiftool -stay_open True -format INDD file path
Response:
Format : application/x-indesign
I would like fetch only below metadata fields to avoid performance issues. I have tried passing only "format" attribute but that didn't work. can you let me know how to exclude or include specific tags?
var includeTags = ['subject',
'document_id',
'original_document_id',
'derived_from_document_id',
'derived_from_original_document_id',
'image*',
'format',
'thumbnail*',
'icc_profile_name',
'color*',
'file_size',
'file_type',
'creator*',
'drm*',
'x_resolution',
'y_resolution',
'file_type_extension',
'file_name']
When I run
exifTool.read(file,
['-config /path/to/exiftool.config', '-n'])`
get the error message: "Invalid TAG name: config"
exiftool.write('path/to/image.jpg', {'Copyright': 'Agent Smith\n1999'})
Fails with a message that the file named "1999" doesn't exist (Error: File not found - 1999
). How can I use newlines in a tag? Any help appreciated :)
I've noticed that there's a branch named node4
but it doesn't seems to work throwing the following error :
path/node_modules/exiftool-vendored/dist/exiftool.js:24
constructor(maxProcs = 1) {
^
SyntaxError: Unexpected token =
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:373:25)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object.<anonymous> (/Users/claudiopetrini/Desktop/test/index-exiftools.js:1:80)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
In the package.json
the supported engine is still "node": ">= 6.4.0"
, is it just an old branch or is there a plan to support Node v4?
Would it be possible to add an example how to edit the macOS "file creation date" ?
This is a special tag called MDItemFSCreationDate
which needs a special option before it can be accessed through exiftool.
From the exiftool docs:
MDItem tags are extracted using the "mdls" utility. They are extracted if any "MDItem*" tag or the MacOS group is specifically requested, or by setting the MDItemTags API option to 1 or the RequestAll API option to 2 or higher.
e.g. -tagsfromfile @ -MDItemFSCreationDate
Hey Matthew short request, any chance of a version bump to the latest version of exiftool v11.21? I would make a PR myself but taking a look at the .exe and perl versions of your library I had no idea about how to go about adding the new version of exiftool to that, a little bit above my paygrade.
All the best,
Josh
Hi, I found some strange chars in dist/ExifTool.d.ts
:
/**
* Use this singleton rather than instantiating new ExifTool instances in order
* to leverage a single running ExifTool process. As of v3.0, its `maxProcs` is
* set to the number of CPUs on the current system; no more than `maxProcs`
* instances of `exiftool` will be spawned. You may want to experiment with
* smaller or larger values for `maxProcs`, depending on CPU and disk speed of
* your system and performance tradeoffs.
*
* Note that each child process consumes between 10 and 50 MB of RAM. If you
* have limited system resources you may want to use a smaller `maxProcs` value.
*/
export declare const exiftool: ExifTool;
ol; // <=This
I tried yarn cache clean
and reinstall it, but it still exist.
The ol;
seems like... I don't know, maybe your cat on keyboard 😆 ?
Describe the bug
Writing ExifDateTime fails with an assertion error.
{ AssertionError [ERR_ASSERTION]: cannot encode {"year":2019,"month":1,"day":1,"hour":0,"minute":0,"second":0}
at enc (...\node_modules\exiftool-vendored\dist\WriteTask.js:73:36)
...
To Reproduce
const exiftool = require("exiftool-vendored").exiftool;
const ExifDateTime = require("exiftool-vendored").ExifDateTime;
test().catch(e => { console.error(e); });
async function test() {
try {
await exiftool.write('test.jpg', {
CreateDate: new ExifDateTime(2019, 1, 1, 0, 0, 0),
});
} finally {
await exiftool.end();
}
}
Environment (please complete the following information):
exiftool-vendored v8.12.0
node v10.10.0
Windows 10
Hi,
Im having trouble cross referencing the tags with the tag names listed on exiftool. For example I'm trying to edit fields such as 'By-Line' and 'Headline' as shown here: https://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/IPTC.html#ApplicationRecord
but cant seem to find any such tags on your list? Might they be labelled under a different name or are those particular fields just not included?
Thanks
I was using this in a Docker Alpine image and got this error:
throw er; // Unhandled 'error' event
^
Error: spawn /opt/bundle/bundle/programs/server/npm/node_modules/exiftool-vendored.pl/bin/exiftool ENOENT
The error was exiftool
failing to start:
exiftool: /usr/bin/perl: bad interpreter: No such file or directory
Because Perl was missing. Alpine Linux aims to be as small as possible, and as such it doesn’t come with Perl installed. One needs to install it (apk add perl
is all it takes).
This isn’t really particular to Alpine though, as anyone might happen to be in an environment that lacks Perl. You might want to mention in the README and/or the wiki that Perl is a dependency that won’t be installed by this package, that the user is responsible for ensuring is available in the environment. I see that the README mentions that Perl will be installed for Windows environments, but presumably that doesn’t happen for Linux.
Great contribution. Thank you!
AFAICT, should be able to scope query to return tags listed in read args array as shown in following example:
read('./image.jpg', ['-Model', '-Make', ...])
Is this unsupported, bug, or on me?
Thanks again,
-Roland.
Hey there,
Thanks again for your great work with this library.
Just having an issue with getting karma + mocha unit tests to run when I include Exiftool
in a file.
I get the following error which I can't seem to figure out the cause of:
Electron 2.0.6 (Node 8.9.3) ERROR
Uncaught Error: Cannot find module "."
at webpack:///node_modules/exiftool-vendored/dist/ExifTool.js:30:0 <- index.js:14977
I have isolated the error in this github repository. Run yarn
followed by yarn run unit
to recreate the error.
Cheers
Hey Matthew,
One thing I've noticed exiftool-vendored is missing is XMP struct tag support.
exiftool has the ability to read and write struct information.
If you want me to have a crack I can but my Typescript is still dire!
Cheers,
Josh
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.