72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
import Image from "next/image";
|
|
import { glob } from "glob";
|
|
import sharp from 'sharp';
|
|
import exifReader from 'exif-reader';
|
|
import { pick } from 'radash';
|
|
import Lightbox from "@/components/lightbox";
|
|
|
|
type ImageData = {
|
|
width: number,
|
|
height: number,
|
|
blur: `data:image/${string}`,
|
|
src: string,
|
|
camera?: string,
|
|
exif: Partial<{
|
|
ExposureBiasValue: number,
|
|
FNumber: number,
|
|
ISOSpeedRatings: number,
|
|
FocalLength: number,
|
|
DateTimeOriginal: Date,
|
|
LensModel: string
|
|
}>
|
|
}
|
|
|
|
export async function getImages(): Promise<{images: ImageData[]}> {
|
|
const photosGlob = await glob(`public/photos/**/*.{png,jpeg,jpg}`, {
|
|
nodir: true,
|
|
});
|
|
|
|
const images = photosGlob.map(async (fileName) => {
|
|
const { width, height, exif } = await sharp(fileName).metadata();
|
|
const blur = await sharp(fileName)
|
|
.resize({ width: 12, height: 12, fit: 'inside' })
|
|
.toBuffer();
|
|
const exifData = exif ? exifReader(exif) : undefined;
|
|
|
|
return {
|
|
width: width ?? 10,
|
|
height: height ?? 10,
|
|
blur: `data:image/jpeg;base64,${blur.toString('base64')}` as `data:image/${string}`,
|
|
src: fileName.slice(6),
|
|
camera: exifData?.Image?.Model,
|
|
exif: pick(exifData?.Photo ?? {}, ['ExposureBiasValue', 'FNumber', 'ISOSpeedRatings', 'FocalLength', 'DateTimeOriginal', 'LensModel'])
|
|
};
|
|
});
|
|
|
|
return { images: await Promise.all(images) };
|
|
}
|
|
|
|
export default async function Home(): Promise<React.JSX.Element> {
|
|
const { images } = await getImages();
|
|
|
|
return (
|
|
<Lightbox imageData={images}>
|
|
{images.map((image) => (
|
|
<div className="relative" key={image.src}>
|
|
<Image
|
|
alt={image.src}
|
|
src={image.src}
|
|
className="object-contain h-auto w-full"
|
|
sizes="(min-width: 808px) 50vw, 100vw"
|
|
loading="lazy"
|
|
width={image.width}
|
|
height={image.height}
|
|
blurDataURL={image.blur}
|
|
placeholder={image.blur}
|
|
/>
|
|
</div>
|
|
))}
|
|
</Lightbox>
|
|
);
|
|
}
|