feat: add exif data to image tags
Some checks failed
Deploy to SFTP Server / build (push) Failing after 1m34s

This commit is contained in:
2024-06-21 16:15:48 +02:00
parent 08c852a9e8
commit e5726437ed
5 changed files with 62 additions and 17 deletions

View File

@ -1,7 +1,7 @@
---
import type { ImageMetadata } from "astro";
import { Picture as AstroImage } from "astro:assets";
import { generateThumbHash } from "@helpers/image";
import { generateThumbHash, getExifData } from "@helpers/image";
interface Props {
src: ImageMetadata;
alt: string;
@ -24,6 +24,8 @@ const {
let thumbhash = hash ? await generateThumbHash(image) : "";
let exif = await getExifData(image);
const sizes = [
{
width: 240,
@ -47,6 +49,7 @@ const sizes = [
src={image}
alt={alt}
data-thumbhash={thumbhash}
data-exif={JSON.stringify(exif)}
pictureAttributes={{
class: `${hash ? "block h-full relative" : ""} ${loader ? "thumb" : ""} ${pictureClass}`,
}}

View File

@ -150,6 +150,7 @@
try {
let rawExif = image.getAttribute("data-exif");
exif = JSON.parse(rawExif);
console.log(exif);
} catch (error) {
// No biggie
}
@ -187,8 +188,7 @@
class:active={currentIndex === i}
on:click={() => {
currentIndex = i;
}}
/>
}} />
{/each}
</div>
{/if}
@ -204,21 +204,18 @@
on:swipe={handleSwipe}
on:wheel|passive={handleScroll}
on:mousemove={handleMouseMove}
on:pointermove={handlePointerMove}
>
on:pointermove={handlePointerMove}>
{#if progress[currentIndex] && progress[currentIndex] < 0.99}
<div
transition:fade
id="progress"
style={`transform: scaleX(${progress[currentIndex]});`}
/>
style={`transform: scaleX(${progress[currentIndex]});`} />
{/if}
<img
class="background"
src={images[currentIndex].preview}
alt="background blur"
/>
alt="background blur" />
<span>
<img
@ -227,15 +224,14 @@
}px ${window.innerHeight - my}px`}
srcset={images[currentIndex].loaded ? "" : images[currentIndex].src}
src={images[currentIndex].loaded}
alt={images[currentIndex].alt}
/>
alt={images[currentIndex].alt} />
</span>
</div>
{#if images[currentIndex].exif}
{@const exif = images[currentIndex].exif}
<div class="exif" on:click={() => console.log(exif)}>
{#if "FocalLength" in exif}
{exif.FocalLength}mm |
{exif.FocalLength} |
{/if}
{#if "FNumber" in exif}

View File

@ -1,16 +1,14 @@
let loadingSharp = false;
import { rgbaToThumbHash } from "thumbhash";
import ExifReader from 'exifreader';
let s: typeof import("sharp") | undefined;
async function getSharp(): Promise<typeof import("sharp") | undefined> {
if (s) return s;
if (import.meta.env.MODE !== "development") {
s = (await import("sharp")).default;
return s;
}
s = (await import("sharp")).default;
return s;
if (!loadingSharp) {
loadingSharp = true;
@ -42,3 +40,33 @@ export async function generateThumbHash(image: { width: number, height: number }
const buffer = rgbaToThumbHash(smallWidth, smallHeight, smallImg);
return Buffer.from(buffer).toString("base64");
}
const allowedExif = [
"ApertureValue",
"DateTimeOriginal",
"ExposureTime",
"ApertureValue",
"FNumber",
"FocalLength",
"GPSLatitude",
"GPSLongitude",
"GPSAltitude",
"IsoSpeedRatings",
];
export async function getExifData(image: { fsPath: string }) {
const sharp = await getSharp();
if (!sharp) return;
const tags = await ExifReader.load(image.fsPath, { async: true });
const out: Record<string, any> = {};
let hasExif = false;
for (const key of allowedExif) {
if (!tags[key]) continue;
hasExif = true;
out[key] = tags[key].description;
}
return hasExif ? out : undefined;
}