Add "tools" section with exif-to-frontmatter tool
ci/woodpecker/push/woodpecker Pipeline was successful Details

recipes
chimo 8 months ago
parent 0f6582d2ce
commit ac8d9bc241

@ -0,0 +1,4 @@
---
title: "Tools"
---

@ -0,0 +1,203 @@
---
title: "EXIF to Frontmatter"
date: "2023-02-04T18:23:53.000Z"
---
<p>
I use this to extract EXIF data from pictures and generate the necessary
Frontmatter for my Hugo "picture" pages. The picture isn't uploaded anywhere;
the data is extracted on the client-side JS using <a
href="https://github.com/exif-js/exif-js">exif.js</a>.
</p>
<input type="file" multiple id="pic" accept="image/*" />
<!-- <div id="dropzone"
style="height: 200px; width: 100%; border: 1px solid #000"></div> -->
<div id="results"></div>
<script src="/js/exif.js"></script>
<script>
( function( doc ) {
'use strict';
let output = doc.querySelector( "#results" ),
/**
* Build frontmatter DOM template out of exif data
*/
getFrontMatterContainer = function ( exif ) {
let image = "tmp",
template = doc.createElement( "template" ),
html = `
<div class="result">
<img src="${image}" />
<pre class="meta">
---
title: ""
date: ""
resources:
- name: original
title: ""
src: images/original.jpg
datetaken: "${exif.dateTaken}"
address1: ""
address2: ""
latitude: "${exif.latitude}"
longitude: "${exif.longitude}"
size: "${exif.size}"
resolution: "${exif.width} x ${exif.height}"
camera: "${exif.make} ${exif.model}"
---
</pre>
</div>
`
template.innerHTML = html.trim();
return template.content.firstChild;
},
/**
* Event handler for files picked from file picker.
*/
processInput = function() {
let files = this.files,
len = files.length,
i;
for ( i = 0; i < len; i += 1 ) {
process( files[ i ] );
}
},
/**
* Entry method to process a file.
*/
process = function( file ) {
extractExif( file )
.then( function( exif ) {
let container = getFrontMatterContainer( exif ),
reader = new FileReader(),
img = container.querySelector( "img" );
output.appendChild( container );
reader.addEventListener( "load", function() {
img.src = reader.result;
} );
reader.readAsDataURL( file );
} );
},
/**
* Convert bytes to easy to read format
*/
readableBytes = function( bytes ) {
let i = Math.floor( Math.log( bytes ) / Math.log( 1024 ) ),
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
return ( bytes / Math.pow( 1024, i ) ).toFixed( 2 ) *
1 + " " + sizes[ i ];
},
/**
* For a given file, extract exif data.
*/
extractExif = function( file ) {
const size = readableBytes( file.size );
return new Promise( function( resolve, reject ) {
EXIF.getData( file, function() {
let exif = EXIF.getAllTags( this ),
latitude = "",
longitude = "",
dateTaken = "",
info = {};
if ( exif.DateTimeOriginal ) {
dateTaken = convertDate( exif.DateTimeOriginal );
}
if ( exif.GPSLatitude ) {
latitude = convertCoords( exif.GPSLatitudeRef,
exif.GPSLatitude );
}
if ( exif.GPSLongitude ) {
longitude = convertCoords( exif.GPSLongitudeRef,
exif.GPSLongitude );
}
info = {
latitude: latitude,
longitude: longitude,
dateTaken: dateTaken,
width: exif.PixelXDimension,
height: exif.PixelYDimension,
make: exif.Make || "",
model: exif.Model || "",
size: size
};
resolve( info );
} );
} );
},
/**
* Event handler when dropping files on the dropzone.
*/
processDroppedImages = function( e ) {
e.preventDefault();
let files = e.dataTransfer.files,
dataUrl;
forEach( function( file ) {
process( file );
} );
},
/**
* Convert date to ISO format.
*/
convertDate = function( datetime ) {
let arr = datetime.split( " " ),
date = arr[ 0 ].replace(/:/g, '-'),
time = arr[ 1 ],
d = new Date( date + " " + time);
return d.toISOString();
},
/**
* Convert coordinate (lat or lon) from degrees to decimal.
*/
convertCoords = function( ref, coord ) {
let direction = 1,
decimalCoords;
if ( ref === 'S' || ref === 'W' ) {
direction = -1;
}
decimalCoords = coord[ 0 ] + ( coord[ 1 ] / 60 ) +
( coord[ 2 ] / 3600 );
return decimalCoords * direction;
};
/*doc.querySelector( "#dropzone" )
.addEventListener( "drop", processDroppedImages );*/
doc.querySelector( "#pic" )
.addEventListener( "change", processInput );
}( document ) );
</script>

@ -3,7 +3,8 @@
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog">Blog</a></li>
<li><a href="https://pics.chromic.org/chimo">Pictures</a></li>
<li><a href="/pictures">Pictures</a></li>
<li><a href="/tools">Tools</a></li>
<li><a href="https://code.chromic.org/chimo">Code</a></li>
</ul>
</nav>

@ -0,0 +1,96 @@
{{ define "tags" }}
{{ $taxo := "tags" }} <!-- Use the plural form here -->
<ul id="{{ $taxo }}" class="entry-tags">
{{ range .Param $taxo }}
{{ $name := . }}
{{ with $.Site.GetPage (printf "/%s/%s" $taxo ($name | urlize)) }}
<li> <a href="{{ .Permalink }}">{{ $name }}</a></li>
{{ end }}
{{ end }}
</ul>
{{ end }}
{{ define "byline" }}
<!-- Author info -->
<div class="entry-author h-card">
<a class="u-url" href="http://chromic.org">
<img alt="Chimo bio photo" class="bio-photo u-photo"
src="/images/bio-photo.png" />
<span class="by-line">
<span class="sr-only">By</span>
<span class="p-author p-name" href="https://chromic.org">Chimo</span>
</span>
</a>
</div>
<!-- Date published -->
<div class="entry-date date published">
<span title="Date published">
<i class="fa fa-calendar-o"></i>
<span class="sr-only">Date published</span>
</span>
<time class="dt-published" datetime="{{ .PublishDate }}">
{{ .PublishDate| dateFormat "Jan. 2, 2006" }}
</time>
</div>
<!-- Date modified -->
<div class="entry-date date modified">
<span title="Date modified">
<i class="fa fa-pencil"></i>
<span class="sr-only">Date modified</span>
</span>
<time class="dt-updated" datetime="{{ .Lastmod }}">
{{ .Lastmod | dateFormat "Jan. 2, 2006" }}
</time>
</div>
{{ end }}
{{ define "main" }}
{{ .Content }}
{{ end }}
{{ define "webmentions" }}
{{ $webmentions := .Resources.Match "webmentions/*" }}
{{ $nb_wm := len $webmentions }}
<section class="webmentions">
<!--<form action="https://webmention.chromic.org/chromic.org/webmention"
class="webmention-form" method="post" id="webmention_form">
<label class="webmention-form__question" for="webmention-url">
Have you written a response to this? Let me know the URL:
</label>
<div class="form-group">
<input class="webmention-form__url" id="webmention-url" name="source"
type="url">
<input class="button btn" type="submit" value="Send Webmention" />
</div>
<input name="target" type="hidden" value="{{ .Permalink }}">
</form>-->
{{ if ne $nb_wm 0 }}
<h1>Webmentions</h1>
<ol class="webmention__list" id="webmentions">
{{ range sort $webmentions ".Params.publishdate" "desc" }}
{{ if eq .Params.type "like-of" }}
<li class="webmention webmention--like">{{ partial "webmentions/like.html" . }}</li>
{{ else if eq .Params.type "repost-of" }}
<li class="webmention webmention--repost">{{ partial "webmentions/repost.html" . }}</li>
{{ else if eq .Params.type "bookmark-of" }}
<li class="webmention webmention--bookmark">{{ partial "webmentions/bookmark.html" . }}</li>
{{ else }}
<li class="webmention webmention--reply">{{ partial "webmentions/reply.html" . }}</li>
{{ end }}
{{ end }}
</ol>
{{ end }}
</section>
{{ end }}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save