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