grain.social is a photo sharing platform built on atproto.
at main 1.3 kB view raw
1export const tags = [ 2 "DateTimeOriginal", 3 "ExposureTime", 4 "FNumber", 5 "Flash", 6 "FocalLengthIn35mmFormat", 7 "ISO", 8 "LensMake", 9 "LensModel", 10 "Make", 11 "Model", 12]; 13 14export const SCALE_FACTOR = 1000000; 15 16export type Exif = Record< 17 string, 18 number | string | boolean | Array<number | string> | undefined | Date 19>; 20 21export function normalizeExif( 22 exif: Exif, 23 scale: number = SCALE_FACTOR, 24): Exif { 25 const normalized: Record< 26 string, 27 number | string | boolean | Array<number | string> | undefined 28 > = {}; 29 30 for (const [key, value] of Object.entries(exif)) { 31 const camelKey = key[0].toLowerCase() + key.slice(1); 32 33 if (typeof value === "number") { 34 normalized[camelKey] = Math.round(value * scale); 35 } else if (Array.isArray(value)) { 36 normalized[camelKey] = value.map((v) => 37 typeof v === "number" ? Math.round(v * scale) : v 38 ); 39 } else if (value instanceof Date) { 40 normalized[camelKey] = value.toISOString(); 41 } else if (typeof value === "string") { 42 normalized[camelKey] = value; 43 } else if (typeof value === "boolean") { 44 normalized[camelKey] = value; 45 } else if (value === undefined) { 46 normalized[camelKey] = undefined; 47 } else { 48 // fallback for unknown types 49 normalized[camelKey] = String(value); 50 } 51 } 52 53 return normalized; 54}