117 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| const fs = require('fs');
 | |
| const util = require('util');
 | |
| const path = require('path');
 | |
| const { read } = require('fast-exif');
 | |
| const iptc = require('node-iptc');
 | |
| const Vibrant = require('node-vibrant');
 | |
| const R = require('ramda');
 | |
| 
 | |
| const readFile = util.promisify(fs.readFile);
 | |
| 
 | |
| 
 | |
| function convertDMSToDD(dms, positiveDirection) {
 | |
|   const res = dms
 | |
|     .map((item, i) => {
 | |
|       return item / Math.pow(60, i);
 | |
|     })
 | |
|     .reduce((a, b) => a + b);
 | |
|   return positiveDirection ? res : -res;
 | |
| }
 | |
| 
 | |
| function transformMetaToNodeData(exifData, iptcData, vibrantData) {
 | |
|   const gps = { longitude: null, latitude: null };
 | |
| 
 | |
|   if (exifData) {
 | |
|     if (
 | |
|       exifData.gps &&
 | |
|       exifData.gps.GPSLongitude &&
 | |
|       exifData.gps.GPSLatitude
 | |
|     ) {
 | |
|       gps.longitude = convertDMSToDD(
 | |
|         exifData.gps.GPSLongitude,
 | |
|         exifData.gps.GPSLongitudeRef === 'E'
 | |
|       );
 | |
|       gps.latitude = convertDMSToDD(
 | |
|         exifData.gps.GPSLatitude,
 | |
|         exifData.gps.GPSLatitudeRef === 'N'
 | |
|       );
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const vibrant = R.map((swatch) => ({
 | |
|     rgb: swatch.getRgb(),
 | |
|     titleTextColor: swatch.getTitleTextColor(),
 | |
|     bodyTextColor: swatch.getBodyTextColor(),
 | |
|   })
 | |
|   , vibrantData);
 | |
| 
 | |
|   return {
 | |
|     exif: exifData?.exif,
 | |
|     gps,
 | |
|     dateTaken: exifData?.exif?.DateTimeOriginal,
 | |
|     iptc: iptcData || undefined,
 | |
|     vibrant,
 | |
|   };
 | |
| }
 | |
| 
 | |
| 
 | |
| exports.onCreateNode = async function ({ node, getNode, actions }) {
 | |
|   const { createNodeField } = actions;
 | |
|   if (node.internal.type === 'ImageSharp') {
 | |
|     const parent = getNode(node.parent);
 | |
| 
 | |
|     const file = await readFile(parent.absolutePath);
 | |
|     const iptcData = iptc(file);
 | |
|     const exifData = await read(parent.absolutePath);
 | |
|     const vibrantData = await Vibrant.from(parent.absolutePath)
 | |
|       .quality(1)
 | |
|       .getPalette();
 | |
| 
 | |
|     createNodeField({
 | |
|       node,
 | |
|       name: 'imageMeta',
 | |
|       value: transformMetaToNodeData(exifData, iptcData, vibrantData),
 | |
|     });
 | |
|   }
 | |
| };
 | |
| 
 | |
| // Implement the Gatsby API “createPages”. This is called once the
 | |
| // data layer is bootstrapped to let plugins create pages from data.
 | |
| exports.createPages = async ({ graphql, actions, reporter }) => {
 | |
|   const { createPage } = actions;
 | |
|   // get all images
 | |
|   const galleryImages = await graphql(`
 | |
|       {
 | |
|         allFile(filter: {
 | |
|           sourceInstanceName: { eq: "gallery" }}
 | |
|         ) {
 | |
|           edges {
 | |
|             node {
 | |
|               relativePath,
 | |
|               base
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     `);
 | |
|   // Handle errors
 | |
|   if (galleryImages.errors) {
 | |
|     reporter.panicOnBuild('Error while running GraphQL query.');
 | |
|     return;
 | |
|   }
 | |
|   // Create pages for each markdown file.
 | |
|   const galleryImageTemplate = path.resolve('src/components/GalleryImage.js');
 | |
|   galleryImages.data.allFile.edges.forEach(({ node }) => {
 | |
|     // const path = node.base
 | |
|     createPage({
 | |
|       path: `photogallery/${node.base}`,
 | |
|       component: galleryImageTemplate,
 | |
|       // In your blog post template's graphql query, you can use pagePath
 | |
|       // as a GraphQL variable to query for data from the markdown file.
 | |
|       context: {
 | |
|         imageFilename: node.base,
 | |
|       },
 | |
|     });
 | |
|   });
 | |
| };
 |