Refine recipe og image
This commit is contained in:
parent
80dfad2fe1
commit
1697a83b95
@ -6,7 +6,7 @@ import {
|
|||||||
import FilmSimulationImageResponse from
|
import FilmSimulationImageResponse from
|
||||||
'@/image-response/FilmSimulationImageResponse';
|
'@/image-response/FilmSimulationImageResponse';
|
||||||
import { FilmSimulation } from '@/simulation';
|
import { FilmSimulation } from '@/simulation';
|
||||||
import { getIBMPlexMonoMedium } from '@/app/font';
|
import { getIBMPlexMono } from '@/app/font';
|
||||||
import { ImageResponse } from 'next/og';
|
import { ImageResponse } from 'next/og';
|
||||||
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
||||||
import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db';
|
import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db';
|
||||||
@ -40,7 +40,7 @@ export async function GET(
|
|||||||
headers,
|
headers,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_PER_CATEGORY, simulation }),
|
getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_PER_CATEGORY, simulation }),
|
||||||
getIBMPlexMonoMedium(),
|
getIBMPlexMono(),
|
||||||
getImageResponseCacheControlHeaders(),
|
getImageResponseCacheControlHeaders(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import {
|
|||||||
IMAGE_OG_DIMENSION_SMALL,
|
IMAGE_OG_DIMENSION_SMALL,
|
||||||
MAX_PHOTOS_TO_SHOW_PER_CATEGORY,
|
MAX_PHOTOS_TO_SHOW_PER_CATEGORY,
|
||||||
} from '@/image-response';
|
} from '@/image-response';
|
||||||
import { getIBMPlexMonoMedium } from '@/app/font';
|
import { getIBMPlexMono } from '@/app/font';
|
||||||
import { ImageResponse } from 'next/og';
|
import { ImageResponse } from 'next/og';
|
||||||
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
||||||
import FocalLengthImageResponse from
|
import FocalLengthImageResponse from
|
||||||
@ -42,7 +42,7 @@ export async function GET(
|
|||||||
headers,
|
headers,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_PER_CATEGORY, focal }),
|
getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_PER_CATEGORY, focal }),
|
||||||
getIBMPlexMonoMedium(),
|
getIBMPlexMono(),
|
||||||
getImageResponseCacheControlHeaders(),
|
getImageResponseCacheControlHeaders(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import {
|
|||||||
MAX_PHOTOS_TO_SHOW_OG,
|
MAX_PHOTOS_TO_SHOW_OG,
|
||||||
} from '@/image-response';
|
} from '@/image-response';
|
||||||
import HomeImageResponse from '@/image-response/HomeImageResponse';
|
import HomeImageResponse from '@/image-response/HomeImageResponse';
|
||||||
import { getIBMPlexMonoMedium } from '@/app/font';
|
import { getIBMPlexMono } from '@/app/font';
|
||||||
import { ImageResponse } from 'next/og';
|
import { ImageResponse } from 'next/og';
|
||||||
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
||||||
import { isNextImageReadyBasedOnPhotos } from '@/photo';
|
import { isNextImageReadyBasedOnPhotos } from '@/photo';
|
||||||
@ -19,7 +19,7 @@ export async function GET() {
|
|||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_OG }).catch(() => []),
|
getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_OG }).catch(() => []),
|
||||||
getImageResponseCacheControlHeaders(),
|
getImageResponseCacheControlHeaders(),
|
||||||
getIBMPlexMonoMedium(),
|
getIBMPlexMono(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const { width, height } = IMAGE_OG_DIMENSION_SMALL;
|
const { width, height } = IMAGE_OG_DIMENSION_SMALL;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { getPhotoCached } from '@/photo/cache';
|
import { getPhotoCached } from '@/photo/cache';
|
||||||
import { IMAGE_OG_DIMENSION } from '@/image-response';
|
import { IMAGE_OG_DIMENSION } from '@/image-response';
|
||||||
import PhotoImageResponse from '@/image-response/PhotoImageResponse';
|
import PhotoImageResponse from '@/image-response/PhotoImageResponse';
|
||||||
import { getIBMPlexMonoMedium } from '@/app/font';
|
import { getIBMPlexMono } from '@/app/font';
|
||||||
import { ImageResponse } from 'next/og';
|
import { ImageResponse } from 'next/og';
|
||||||
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
||||||
import {
|
import {
|
||||||
@ -34,7 +34,7 @@ export async function GET(
|
|||||||
headers,
|
headers,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
getPhotoCached(photoId),
|
getPhotoCached(photoId),
|
||||||
getIBMPlexMonoMedium(),
|
getIBMPlexMono(),
|
||||||
getImageResponseCacheControlHeaders(),
|
getImageResponseCacheControlHeaders(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import {
|
|||||||
IMAGE_OG_DIMENSION_SMALL,
|
IMAGE_OG_DIMENSION_SMALL,
|
||||||
MAX_PHOTOS_TO_SHOW_PER_CATEGORY,
|
MAX_PHOTOS_TO_SHOW_PER_CATEGORY,
|
||||||
} from '@/image-response';
|
} from '@/image-response';
|
||||||
import { getIBMPlexMonoMedium } from '@/app/font';
|
import { getIBMPlexMono } from '@/app/font';
|
||||||
import { ImageResponse } from 'next/og';
|
import { ImageResponse } from 'next/og';
|
||||||
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
||||||
import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db';
|
import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db';
|
||||||
@ -38,7 +38,7 @@ export async function GET(
|
|||||||
headers,
|
headers,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
getPhotosCached({ recipe, limit: MAX_PHOTOS_TO_SHOW_PER_CATEGORY }),
|
getPhotosCached({ recipe, limit: MAX_PHOTOS_TO_SHOW_PER_CATEGORY }),
|
||||||
getIBMPlexMonoMedium(),
|
getIBMPlexMono(),
|
||||||
getImageResponseCacheControlHeaders(),
|
getImageResponseCacheControlHeaders(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import {
|
|||||||
MAX_PHOTOS_TO_SHOW_PER_CATEGORY,
|
MAX_PHOTOS_TO_SHOW_PER_CATEGORY,
|
||||||
} from '@/image-response';
|
} from '@/image-response';
|
||||||
import CameraImageResponse from '@/image-response/CameraImageResponse';
|
import CameraImageResponse from '@/image-response/CameraImageResponse';
|
||||||
import { getIBMPlexMonoMedium } from '@/app/font';
|
import { getIBMPlexMono } from '@/app/font';
|
||||||
import { ImageResponse } from 'next/og';
|
import { ImageResponse } from 'next/og';
|
||||||
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
||||||
import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db';
|
import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db';
|
||||||
@ -42,7 +42,7 @@ export async function GET(
|
|||||||
limit: MAX_PHOTOS_TO_SHOW_PER_CATEGORY,
|
limit: MAX_PHOTOS_TO_SHOW_PER_CATEGORY,
|
||||||
camera: camera,
|
camera: camera,
|
||||||
}),
|
}),
|
||||||
getIBMPlexMonoMedium(),
|
getIBMPlexMono(),
|
||||||
getImageResponseCacheControlHeaders(),
|
getImageResponseCacheControlHeaders(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import {
|
|||||||
MAX_PHOTOS_TO_SHOW_PER_CATEGORY,
|
MAX_PHOTOS_TO_SHOW_PER_CATEGORY,
|
||||||
} from '@/image-response';
|
} from '@/image-response';
|
||||||
import TagImageResponse from '@/image-response/TagImageResponse';
|
import TagImageResponse from '@/image-response/TagImageResponse';
|
||||||
import { getIBMPlexMonoMedium } from '@/app/font';
|
import { getIBMPlexMono } from '@/app/font';
|
||||||
import { ImageResponse } from 'next/og';
|
import { ImageResponse } from 'next/og';
|
||||||
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
||||||
import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db';
|
import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db';
|
||||||
@ -38,7 +38,7 @@ export async function GET(
|
|||||||
headers,
|
headers,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_PER_CATEGORY, tag }),
|
getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_PER_CATEGORY, tag }),
|
||||||
getIBMPlexMonoMedium(),
|
getIBMPlexMono(),
|
||||||
getImageResponseCacheControlHeaders(),
|
getImageResponseCacheControlHeaders(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import {
|
|||||||
} from '@/image-response';
|
} from '@/image-response';
|
||||||
import TemplateImageResponse from
|
import TemplateImageResponse from
|
||||||
'@/image-response/TemplateImageResponse';
|
'@/image-response/TemplateImageResponse';
|
||||||
import { getIBMPlexMonoMedium } from '@/app/font';
|
import { getIBMPlexMono } from '@/app/font';
|
||||||
import { ImageResponse } from 'next/og';
|
import { ImageResponse } from 'next/og';
|
||||||
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
||||||
import { isNextImageReadyBasedOnPhotos } from '@/photo';
|
import { isNextImageReadyBasedOnPhotos } from '@/photo';
|
||||||
@ -20,7 +20,7 @@ export async function GET() {
|
|||||||
sortBy: 'priority',
|
sortBy: 'priority',
|
||||||
limit: MAX_PHOTOS_TO_SHOW_TEMPLATE_TIGHT,
|
limit: MAX_PHOTOS_TO_SHOW_TEMPLATE_TIGHT,
|
||||||
}).catch(() => []),
|
}).catch(() => []),
|
||||||
getIBMPlexMonoMedium(),
|
getIBMPlexMono(),
|
||||||
getImageResponseCacheControlHeaders(),
|
getImageResponseCacheControlHeaders(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import {
|
|||||||
} from '@/image-response';
|
} from '@/image-response';
|
||||||
import TemplateImageResponse from
|
import TemplateImageResponse from
|
||||||
'@/image-response/TemplateImageResponse';
|
'@/image-response/TemplateImageResponse';
|
||||||
import { getIBMPlexMonoMedium } from '@/app/font';
|
import { getIBMPlexMono } from '@/app/font';
|
||||||
import { ImageResponse } from 'next/og';
|
import { ImageResponse } from 'next/og';
|
||||||
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
|
||||||
import { isNextImageReadyBasedOnPhotos } from '@/photo';
|
import { isNextImageReadyBasedOnPhotos } from '@/photo';
|
||||||
@ -20,7 +20,7 @@ export async function GET() {
|
|||||||
sortBy: 'priority',
|
sortBy: 'priority',
|
||||||
limit: MAX_PHOTOS_TO_SHOW_TEMPLATE,
|
limit: MAX_PHOTOS_TO_SHOW_TEMPLATE,
|
||||||
}).catch(() => []),
|
}).catch(() => []),
|
||||||
getIBMPlexMonoMedium(),
|
getIBMPlexMono(),
|
||||||
getImageResponseCacheControlHeaders(),
|
getImageResponseCacheControlHeaders(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@ -3,18 +3,31 @@ import path from 'path';
|
|||||||
import { cwd } from 'process';
|
import { cwd } from 'process';
|
||||||
|
|
||||||
const FONT_IBM_PLEX_MONO_FAMILY = 'IBMPlexMono';
|
const FONT_IBM_PLEX_MONO_FAMILY = 'IBMPlexMono';
|
||||||
const FONT_IBM_PLEX_MONO_PATH = '/public/fonts/IBMPlexMono-Medium.ttf';
|
|
||||||
|
|
||||||
const getFontData = async () =>
|
const FONT_IBM_PLEX_MONO_PATH_REGULAR = '/public/fonts/IBMPlexMono-Regular.ttf';
|
||||||
fs.readFileSync(path.join(cwd(), FONT_IBM_PLEX_MONO_PATH));
|
const FONT_IBM_PLEX_MONO_PATH_MEDIUM = '/public/fonts/IBMPlexMono-Medium.ttf';
|
||||||
|
|
||||||
export const getIBMPlexMonoMedium = () => getFontData()
|
const getFontData = async (fontPath: string) =>
|
||||||
.then(data => ({
|
fs.readFileSync(path.join(cwd(), fontPath));
|
||||||
|
|
||||||
|
export const getIBMPlexMono = async () => {
|
||||||
|
const [regular, medium] = await Promise.all([
|
||||||
|
getFontData(FONT_IBM_PLEX_MONO_PATH_REGULAR),
|
||||||
|
getFontData(FONT_IBM_PLEX_MONO_PATH_MEDIUM),
|
||||||
|
]);
|
||||||
|
return {
|
||||||
fontFamily: FONT_IBM_PLEX_MONO_FAMILY,
|
fontFamily: FONT_IBM_PLEX_MONO_FAMILY,
|
||||||
fonts: [{
|
fonts: [{
|
||||||
name: FONT_IBM_PLEX_MONO_FAMILY,
|
name: FONT_IBM_PLEX_MONO_FAMILY,
|
||||||
data,
|
data: regular,
|
||||||
|
weight: 400,
|
||||||
|
style: 'normal',
|
||||||
|
} as const, {
|
||||||
|
name: FONT_IBM_PLEX_MONO_FAMILY,
|
||||||
|
data: medium,
|
||||||
weight: 500,
|
weight: 500,
|
||||||
style: 'normal',
|
style: 'normal',
|
||||||
} as const],
|
} as const,
|
||||||
}));
|
],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
@ -15,12 +15,14 @@ export default function RecipeImageResponse({
|
|||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
fontFamily,
|
fontFamily,
|
||||||
|
smallText = true,
|
||||||
}: {
|
}: {
|
||||||
recipe: string,
|
recipe: string,
|
||||||
photos: Photo[]
|
photos: Photo[]
|
||||||
width: NextImageSize
|
width: NextImageSize
|
||||||
height: number
|
height: number
|
||||||
fontFamily: string
|
fontFamily: string
|
||||||
|
smallText?: boolean
|
||||||
}) {
|
}) {
|
||||||
const photo = getPhotoWithRecipeFromPhotos(photos);
|
const photo = getPhotoWithRecipeFromPhotos(photos);
|
||||||
|
|
||||||
@ -51,7 +53,7 @@ export default function RecipeImageResponse({
|
|||||||
tw="flex absolute inset-0"
|
tw="flex absolute inset-0"
|
||||||
style={{
|
style={{
|
||||||
background:
|
background:
|
||||||
'linear-gradient(to right, rgba(0, 0, 0, .5) 40%, transparent 75%)',
|
'linear-gradient(to right, rgba(0, 0, 0, .5) 30%, transparent 60%)',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<ImageCaption {...{
|
<ImageCaption {...{
|
||||||
@ -71,12 +73,19 @@ export default function RecipeImageResponse({
|
|||||||
}}>
|
}}>
|
||||||
{photo?.recipeData &&
|
{photo?.recipeData &&
|
||||||
<div
|
<div
|
||||||
tw="opacity-60"
|
// tw="opacity-70"
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
|
...smallText ? {
|
||||||
paddingTop: height * .03,
|
paddingTop: height * .03,
|
||||||
lineHeight: 1.22,
|
lineHeight: 1.45,
|
||||||
|
letterSpacing: '0.03em',
|
||||||
|
fontSize: height * .06,
|
||||||
|
} : {
|
||||||
|
paddingTop: height * .02,
|
||||||
|
opacity: 0.7,
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{recipeLines.map(text => (
|
{recipeLines.map(text => (
|
||||||
|
|||||||
@ -33,6 +33,7 @@ export default function ImageCaption({
|
|||||||
color: 'white',
|
color: 'white',
|
||||||
backgroundBlendMode: 'multiply',
|
backgroundBlendMode: 'multiply',
|
||||||
fontFamily,
|
fontFamily,
|
||||||
|
fontWeight: 500,
|
||||||
fontSize: height *.08,
|
fontSize: height *.08,
|
||||||
gap,
|
gap,
|
||||||
lineHeight: 1.2,
|
lineHeight: 1.2,
|
||||||
|
|||||||
@ -59,19 +59,18 @@ export const generateRecipeText = ({
|
|||||||
simulation,
|
simulation,
|
||||||
}: RecipeProps) => {
|
}: RecipeProps) => {
|
||||||
const lines = [
|
const lines = [
|
||||||
`${labelForFilmSimulation(simulation).large.toLocaleUpperCase()}`,
|
`${labelForFilmSimulation(simulation).small.toLocaleUpperCase()}`,
|
||||||
`DR${recipe.dynamicRange.development} NR${formatNoiseReduction(recipe)}`,
|
`DR${recipe.dynamicRange.development} NR${formatNoiseReduction(recipe)}`,
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
`${formatWhiteBalance(recipe).toLocaleUpperCase()} ${formatWhiteBalanceColor(recipe)}`,
|
`${formatWhiteBalance(recipe).toLocaleUpperCase()} ${formatWhiteBalanceColor(recipe)}`,
|
||||||
];
|
];
|
||||||
|
|
||||||
if (recipe.highlight || recipe.shadow) {
|
if (recipe.highlight || recipe.shadow) {
|
||||||
// eslint-disable-next-line max-len
|
lines.push(`HI/SH ${addSign(recipe.highlight)}/${addSign(recipe.shadow)}`);
|
||||||
lines.push(`HIGH/SHAD ${addSign(recipe.highlight)}/${addSign(recipe.shadow)}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
lines.push(`COL${addSign(recipe.color)} SHARP${addSign(recipe.sharpness)} CLAR${addSign(recipe.clarity)}`);
|
lines.push(`CO${addSign(recipe.color)} SH${addSign(recipe.sharpness)} CL${addSign(recipe.clarity)}`);
|
||||||
|
|
||||||
if (recipe.colorChromeEffect) {
|
if (recipe.colorChromeEffect) {
|
||||||
lines.push(`CHROME ${recipe.colorChromeEffect.toLocaleUpperCase()}`);
|
lines.push(`CHROME ${recipe.colorChromeEffect.toLocaleUpperCase()}`);
|
||||||
@ -141,15 +140,15 @@ export const formatWhiteBalanceColor = ({
|
|||||||
whiteBalance: { red, blue },
|
whiteBalance: { red, blue },
|
||||||
}: FujifilmRecipe) =>
|
}: FujifilmRecipe) =>
|
||||||
(red || blue)
|
(red || blue)
|
||||||
? `(R${addSign(red)}/B${addSign(blue)})`
|
? `R${addSign(red)}/B${addSign(blue)}`
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
export const formatGrain = ({ grainEffect }: FujifilmRecipe) =>
|
export const formatGrain = ({ grainEffect }: FujifilmRecipe) =>
|
||||||
grainEffect.roughness === 'off'
|
grainEffect.roughness === 'off'
|
||||||
? 'OFF'
|
? 'OFF'
|
||||||
: grainEffect.roughness === 'weak'
|
: grainEffect.roughness === 'weak'
|
||||||
? `WEAK/${grainEffect.size.toLocaleUpperCase()}`
|
? `WEAK/${grainEffect.size === 'small' ? 'SM' : 'LG'}`
|
||||||
: `STRONG/${grainEffect.size.toLocaleUpperCase()}`;
|
: `STRONG/${grainEffect.size === 'small' ? 'SM' : 'LG'}`;
|
||||||
|
|
||||||
export const formatNoiseReduction = ({
|
export const formatNoiseReduction = ({
|
||||||
highISONoiseReduction,
|
highISONoiseReduction,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user