Swap photo metadata parsers
This commit is contained in:
parent
40ad616098
commit
846db750fc
@ -1,14 +1,9 @@
|
|||||||
const fs = require("fs");
|
|
||||||
const util = require("util");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const { read } = require("fast-exif");
|
|
||||||
const iptc = require("node-iptc");
|
|
||||||
const Vibrant = require("node-vibrant");
|
const Vibrant = require("node-vibrant");
|
||||||
const chroma = require("chroma-js");
|
const chroma = require("chroma-js");
|
||||||
const chalk = require("chalk");
|
const chalk = require("chalk");
|
||||||
const R = require("ramda");
|
const R = require("ramda");
|
||||||
|
const exifr = require("exifr");
|
||||||
const readFile = util.promisify(fs.readFile);
|
|
||||||
|
|
||||||
const badContrast = (color1, color2) => chroma.contrast(color1, color2) < 4.5;
|
const badContrast = (color1, color2) => chroma.contrast(color1, color2) < 4.5;
|
||||||
|
|
||||||
@ -89,32 +84,27 @@ function convertDMSToDD(dms, positiveDirection) {
|
|||||||
return positiveDirection ? res : -res;
|
return positiveDirection ? res : -res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformMetaToNodeData(exifData, iptcData, vibrantData, imagePath) {
|
function transformMetaToNodeData(metaData, vibrantData, imagePath) {
|
||||||
const gps = { longitude: null, latitude: null };
|
// const gps = { longitude: null, latitude: null };
|
||||||
|
|
||||||
if (exifData) {
|
// if (exifData) {
|
||||||
if (exifData.gps && exifData.gps.GPSLongitude && exifData.gps.GPSLatitude) {
|
// if (exifData.gps && exifData.gps.GPSLongitude && exifData.gps.GPSLatitude) {
|
||||||
gps.longitude = convertDMSToDD(
|
// gps.longitude = convertDMSToDD(
|
||||||
exifData.gps.GPSLongitude,
|
// exifData.gps.GPSLongitude,
|
||||||
exifData.gps.GPSLongitudeRef === "E"
|
// exifData.gps.GPSLongitudeRef === "E"
|
||||||
);
|
// );
|
||||||
gps.latitude = convertDMSToDD(
|
// gps.latitude = convertDMSToDD(
|
||||||
exifData.gps.GPSLatitude,
|
// exifData.gps.GPSLatitude,
|
||||||
exifData.gps.GPSLatitudeRef === "N"
|
// exifData.gps.GPSLatitudeRef === "N"
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
const vibrant = vibrantData ? processColors(vibrantData, imagePath) : null;
|
const vibrant = vibrantData ? processColors(vibrantData, imagePath) : null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
exif: {
|
dateTaken: metaData.DateTimeOriginal,
|
||||||
...exifData?.exif,
|
meta: metaData,
|
||||||
...exifData?.image
|
|
||||||
},
|
|
||||||
gps,
|
|
||||||
dateTaken: exifData?.exif?.DateTimeOriginal,
|
|
||||||
iptc: iptcData || undefined,
|
|
||||||
vibrant,
|
vibrant,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -122,9 +112,11 @@ function transformMetaToNodeData(exifData, iptcData, vibrantData, imagePath) {
|
|||||||
exports.onCreateNode = async function ({ node, actions }) {
|
exports.onCreateNode = async function ({ node, actions }) {
|
||||||
const { createNodeField } = actions;
|
const { createNodeField } = actions;
|
||||||
if (node.internal.type === "File" && node.sourceInstanceName === "gallery") {
|
if (node.internal.type === "File" && node.sourceInstanceName === "gallery") {
|
||||||
const file = await readFile(node.absolutePath);
|
const metaData = await exifr.parse(node.absolutePath, {
|
||||||
const iptcData = iptc(file);
|
iptc: true,
|
||||||
const exifData = await read(node.absolutePath);
|
xmp: true,
|
||||||
|
// icc: true
|
||||||
|
});
|
||||||
const vibrantData = await Vibrant.from(node.absolutePath)
|
const vibrantData = await Vibrant.from(node.absolutePath)
|
||||||
.quality(3)
|
.quality(3)
|
||||||
.getPalette();
|
.getPalette();
|
||||||
@ -132,12 +124,7 @@ exports.onCreateNode = async function ({ node, actions }) {
|
|||||||
createNodeField({
|
createNodeField({
|
||||||
node,
|
node,
|
||||||
name: "imageMeta",
|
name: "imageMeta",
|
||||||
value: transformMetaToNodeData(
|
value: transformMetaToNodeData(metaData, vibrantData, node.absolutePath),
|
||||||
exifData,
|
|
||||||
iptcData,
|
|
||||||
vibrantData,
|
|
||||||
node.absolutePath
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
"eslint-plugin-react": "^7.24.0",
|
"eslint-plugin-react": "^7.24.0",
|
||||||
"eslint-plugin-react-hooks": "^4.2.0",
|
"eslint-plugin-react-hooks": "^4.2.0",
|
||||||
"eslint-webpack-plugin": "^2.5.4",
|
"eslint-webpack-plugin": "^2.5.4",
|
||||||
|
"exifr": "^7.1.3",
|
||||||
"fast-exif": "^1.0.1",
|
"fast-exif": "^1.0.1",
|
||||||
"gatsby": "^3.4.1",
|
"gatsby": "^3.4.1",
|
||||||
"gatsby-plugin-eslint": "^3.0.0",
|
"gatsby-plugin-eslint": "^3.0.0",
|
||||||
|
@ -60,10 +60,11 @@ const GalleryImage = ({ data, pageContext }) => {
|
|||||||
}, [pageContext]);
|
}, [pageContext]);
|
||||||
|
|
||||||
const name = getName(image);
|
const name = getName(image);
|
||||||
const meta = getMeta(image);
|
const {meta, dateTaken: dt} = getMeta(image);
|
||||||
|
// const locationString = meta.City;
|
||||||
let locationString;
|
let locationString;
|
||||||
if (meta.iptc.city || meta.iptc.province_or_state) {
|
if (meta.City || meta.State || meta.Location) {
|
||||||
const location = [meta.iptc.city, meta.iptc.province_or_state].filter(
|
const location = [meta.Location, meta.City, meta.State].filter(
|
||||||
Boolean
|
Boolean
|
||||||
);
|
);
|
||||||
locationString = location.join(", ");
|
locationString = location.join(", ");
|
||||||
@ -75,10 +76,10 @@ const GalleryImage = ({ data, pageContext }) => {
|
|||||||
? "flex-col mx-auto"
|
? "flex-col mx-auto"
|
||||||
: "portrait:mx-auto landscape:mx-5 landscape:flex-row-reverse portrait:flex-col";
|
: "portrait:mx-auto landscape:mx-5 landscape:flex-row-reverse portrait:flex-col";
|
||||||
const shutterSpeed = React.useMemo(
|
const shutterSpeed = React.useMemo(
|
||||||
() => getShutterFractionFromExposureTime(meta.exif.ExposureTime || 0),
|
() => getShutterFractionFromExposureTime(meta.ExposureTime || 0),
|
||||||
[meta]
|
[meta]
|
||||||
);
|
);
|
||||||
const dateTaken = React.useMemo(() => new Date(meta.dateTaken), [meta]);
|
const dateTaken = React.useMemo(() => new Date(dt), [dt]);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<Helmet>
|
||||||
@ -144,7 +145,7 @@ const GalleryImage = ({ data, pageContext }) => {
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={classnames(
|
className={classnames(
|
||||||
"mx-2 flex flex-row portrait:items-end",
|
"px-2 flex flex-row portrait:items-end container mx-auto",
|
||||||
ar <= 1
|
ar <= 1
|
||||||
? "pt-5 flex-col flex-auto text-right"
|
? "pt-5 flex-col flex-auto text-right"
|
||||||
: "portrait:pt-5 portrait:flex-col portrait:text-right"
|
: "portrait:pt-5 portrait:flex-col portrait:text-right"
|
||||||
@ -157,7 +158,7 @@ const GalleryImage = ({ data, pageContext }) => {
|
|||||||
{hasName(image) && (
|
{hasName(image) && (
|
||||||
<h1 className="text-4xl mt-0 font-serif">{name}</h1>
|
<h1 className="text-4xl mt-0 font-serif">{name}</h1>
|
||||||
)}
|
)}
|
||||||
<p className="landscape:mr-2">{meta.iptc.caption}</p>
|
<p className="landscape:mr-2">{meta.Caption}</p>
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
<div
|
<div
|
||||||
@ -173,21 +174,21 @@ const GalleryImage = ({ data, pageContext }) => {
|
|||||||
/>
|
/>
|
||||||
<MetadataItem
|
<MetadataItem
|
||||||
data={locationString}
|
data={locationString}
|
||||||
icon="location"
|
icon="map-outline"
|
||||||
title="location"
|
title="location"
|
||||||
/>
|
/>
|
||||||
{(meta.exif.Make || meta.exif.Model) && (
|
{(meta.Make || meta.Model) && (
|
||||||
<MetadataItem
|
<MetadataItem
|
||||||
data={[meta.exif.Make, meta.exif.Model].join(" ")}
|
data={[meta.Make, meta.Model].join(" ")}
|
||||||
icon="camera-outline"
|
icon="camera-outline"
|
||||||
title="camera"
|
title="camera"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{(meta.exif.LensModel || meta.exif.FocalLength) && (
|
{(meta.LensModel || meta.FocalLength) && (
|
||||||
<MetadataItem
|
<MetadataItem
|
||||||
data={[
|
data={[
|
||||||
meta.exif.LensModel === "----" ? null : meta.exif.LensModel,
|
meta.LensModel === "----" ? null : meta.LensModel,
|
||||||
meta.exif.FocalLength && `${meta.exif.FocalLength}mm`,
|
meta.FocalLength && `${meta.FocalLength}mm`,
|
||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(" @")}
|
.join(" @")}
|
||||||
@ -200,15 +201,15 @@ const GalleryImage = ({ data, pageContext }) => {
|
|||||||
icon="stopwatch-outline"
|
icon="stopwatch-outline"
|
||||||
title="shutter speed"
|
title="shutter speed"
|
||||||
/>
|
/>
|
||||||
{meta.exif.FNumber && (
|
{meta.FNumber && (
|
||||||
<MetadataItem
|
<MetadataItem
|
||||||
data={`f/${meta.exif.FNumber}`}
|
data={`f/${meta.FNumber}`}
|
||||||
icon="aperture-outline"
|
icon="aperture-outline"
|
||||||
title="aperture"
|
title="aperture"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<MetadataItem
|
<MetadataItem
|
||||||
data={meta.exif.ISO}
|
data={meta.ISO}
|
||||||
icon="film-outline"
|
icon="film-outline"
|
||||||
title="ISO"
|
title="ISO"
|
||||||
/>
|
/>
|
||||||
@ -247,21 +248,23 @@ export const query = graphql`
|
|||||||
fields {
|
fields {
|
||||||
imageMeta {
|
imageMeta {
|
||||||
dateTaken
|
dateTaken
|
||||||
iptc {
|
meta {
|
||||||
caption
|
|
||||||
object_name
|
|
||||||
keywords
|
|
||||||
city
|
|
||||||
province_or_state
|
|
||||||
}
|
|
||||||
exif {
|
|
||||||
FNumber
|
|
||||||
ExposureTime
|
|
||||||
FocalLength
|
|
||||||
ISO
|
|
||||||
LensModel
|
|
||||||
Make
|
Make
|
||||||
Model
|
Model
|
||||||
|
ExposureTime
|
||||||
|
FNumber
|
||||||
|
ISO
|
||||||
|
DateTimeOriginal
|
||||||
|
CreateDate
|
||||||
|
ShutterSpeedValue
|
||||||
|
ApertureValue
|
||||||
|
FocalLength
|
||||||
|
LensModel
|
||||||
|
ObjectName
|
||||||
|
Caption
|
||||||
|
Location
|
||||||
|
City
|
||||||
|
State
|
||||||
}
|
}
|
||||||
vibrant {
|
vibrant {
|
||||||
...VibrantColors
|
...VibrantColors
|
||||||
|
@ -81,9 +81,7 @@ export const query = graphql`
|
|||||||
fields {
|
fields {
|
||||||
imageMeta {
|
imageMeta {
|
||||||
dateTaken
|
dateTaken
|
||||||
iptc {
|
ObjectName
|
||||||
object_name
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
export const getMeta = (image) => image.fields.imageMeta;
|
export const getMeta = (image) => image.fields.imageMeta;
|
||||||
|
|
||||||
export const getName = (image) =>
|
export const getName = (image) =>
|
||||||
getMeta(image)?.iptc.object_name || image.base;
|
getMeta(image)?.meta?.ObjectName || image.base;
|
||||||
|
|
||||||
// some pleasing default colors for SSR and initial hydration
|
// some pleasing default colors for SSR and initial hydration
|
||||||
export const getVibrant = (image) => getMeta(image)?.vibrant;
|
export const getVibrant = (image) => getMeta(image)?.vibrant;
|
||||||
|
|
||||||
export const hasName = (image) => Boolean(getMeta(image)?.iptc.object_name);
|
export const hasName = (image) => Boolean(getMeta(image)?.meta?.ObjectName);
|
||||||
|
|
||||||
export const getAspectRatio = (image) =>
|
export const getAspectRatio = (image) =>
|
||||||
image.childImageSharp.fluid.aspectRatio;
|
image.childImageSharp.fluid.aspectRatio;
|
||||||
|
@ -5681,6 +5681,11 @@ exif-reader@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/exif-reader/-/exif-reader-1.0.3.tgz#8eb63f878aeb49ec89bd5b7be10e393db78c3c2e"
|
resolved "https://registry.yarnpkg.com/exif-reader/-/exif-reader-1.0.3.tgz#8eb63f878aeb49ec89bd5b7be10e393db78c3c2e"
|
||||||
integrity sha512-tWMBj1+9jUSibgR/kv/GQ/fkR0biaN9GEZ5iPdf7jFeH//d2bSzgPoaWf1OfMv4MXFD4upwvpCCyeMvSyLWSfA==
|
integrity sha512-tWMBj1+9jUSibgR/kv/GQ/fkR0biaN9GEZ5iPdf7jFeH//d2bSzgPoaWf1OfMv4MXFD4upwvpCCyeMvSyLWSfA==
|
||||||
|
|
||||||
|
exifr@^7.1.3:
|
||||||
|
version "7.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/exifr/-/exifr-7.1.3.tgz#f6218012c36dbb7d843222011b27f065fddbab6f"
|
||||||
|
integrity sha512-g/aje2noHivrRSLbAUtBPWFbxKdKhgj/xr1vATDdUXPOFYJlQ62Ft0oy+72V6XLIpDJfHs6gXLbBLAolqOXYRw==
|
||||||
|
|
||||||
expand-brackets@^2.1.4:
|
expand-brackets@^2.1.4:
|
||||||
version "2.1.4"
|
version "2.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
|
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user