60 lines
1.8 KiB
TypeScript
60 lines
1.8 KiB
TypeScript
import type { ExifData } from 'ts-exif-parser';
|
|
|
|
const OFFSET_REGEX = /[+-]\d\d:\d\d/;
|
|
|
|
export const getOffsetFromExif = (data: ExifData) =>
|
|
Object.values(data.tags as any)
|
|
.find((value: any) =>
|
|
typeof value === 'string' &&
|
|
OFFSET_REGEX.test(value)
|
|
) as string | undefined;
|
|
|
|
export const formatFocalLength = (focalLength?: number) =>
|
|
focalLength !== undefined ? `${focalLength}mm` : undefined;
|
|
|
|
export const formatAperture = (aperture?: number) =>
|
|
aperture !== undefined ? `ƒ/${aperture}` : undefined;
|
|
|
|
export const formatIso = (iso?: number) =>
|
|
iso !== undefined ? `ISO ${iso}` : undefined;
|
|
|
|
export const formatExposureTime = (exposureTime?: number) =>
|
|
exposureTime !== undefined
|
|
? `Shutter 1/${Math.floor(1 / (exposureTime ?? 1))}`
|
|
: undefined;
|
|
|
|
const fractionForDecimal = (decimal: number, fractionCharacter?: boolean) => {
|
|
switch (Math.abs(Math.floor(decimal * 100))) {
|
|
case 33:
|
|
return fractionCharacter ? '⅓' : '1/3';
|
|
case 50:
|
|
return fractionCharacter ? '½' : '1/2';
|
|
case 66:
|
|
case 67:
|
|
return fractionCharacter ? '⅔' : '2/3';
|
|
}
|
|
};
|
|
|
|
export const formatExposureCompensation = (exposureCompensation?: number) => {
|
|
if (exposureCompensation) {
|
|
const decimal = exposureCompensation % 1;
|
|
const whole = Math.abs(exposureCompensation - decimal);
|
|
const fraction = fractionForDecimal(decimal);
|
|
const sign = exposureCompensation > 0 ? '+' : '-';
|
|
return `${sign}${whole ? `${whole} ` : ''}${fraction ?? ''} EV`;
|
|
} else {
|
|
return undefined;
|
|
}
|
|
};
|
|
|
|
export const formatModelShort = (model?: string) => {
|
|
const textLength = model?.length ?? 0;
|
|
if (textLength > 0 && textLength <= 8) {
|
|
return model;
|
|
} else if (model?.includes('iPhone')) {
|
|
return model.split('iPhone')[1];
|
|
} else {
|
|
return undefined;
|
|
}
|
|
};
|