Skip to content

Commit

Permalink
画像周りをテコ入れ
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-20 committed Mar 23, 2024
1 parent 42cfe0b commit 0cf8ce7
Show file tree
Hide file tree
Showing 104 changed files with 32 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { Link } from '../../../foundation/components/Link';
import { Separator } from '../../../foundation/components/Separator';
import { Spacer } from '../../../foundation/components/Spacer';
import { Text } from '../../../foundation/components/Text';
import { useImage } from '../../../foundation/hooks/useImage';
import { Color, Radius, Space, Typography } from '../../../foundation/styles/variables';

const _Wrapper = styled.li`
Expand All @@ -34,7 +33,7 @@ type Props = {
};

export const EpisodeListItem: React.FC<Props> = ({ bookId, episode }) => {
const imageUrl = useImage({ height: 96, imageId: episode.image.id, width: 96 });
const imageUrl = `/raw-images/${episode.image.id}_96x96.avif`;

return (
<_Wrapper>
Expand Down
49 changes: 7 additions & 42 deletions workspaces/app/src/foundation/hooks/useImage.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,11 @@
import { useAsync } from 'react-use';

import { getImageUrl } from '../../lib/image/getImageUrl';

export const useImage = ({ height, imageId, width }: { height: number; imageId: string; width: number }) => {
const { value } = useAsync(async () => {
const dpr = window.devicePixelRatio;

const img = new Image();
img.src = getImageUrl({
format: 'jpg',
height: height * dpr,
imageId,
width: width * dpr,
});

await img.decode();

const canvas = document.createElement('canvas');
canvas.width = width * dpr;
canvas.height = height * dpr;
const ctx = canvas.getContext('2d')!;

// Draw image to canvas as object-fit: cover
const imgAspect = img.naturalWidth / img.naturalHeight;
const targetAspect = width / height;

if (imgAspect > targetAspect) {
const srcW = img.naturalHeight * targetAspect;
const srcH = img.naturalHeight;
const srcX = (img.naturalWidth - srcW) / 2;
const srcY = 0;
ctx.drawImage(img, srcX, srcY, srcW, srcH, 0, 0, width * dpr, height * dpr);
} else {
const srcW = img.naturalWidth;
const srcH = img.naturalWidth / targetAspect;
const srcX = 0;
const srcY = (img.naturalHeight - srcH) / 2;
ctx.drawImage(img, srcX, srcY, srcW, srcH, 0, 0, width * dpr, height * dpr);
}

return canvas.toDataURL('image/png');
}, [height, imageId, width]);

return value;
const dpr = window.devicePixelRatio;
return getImageUrl({
format: 'avif',
height: height * dpr,
imageId,
width: width * dpr,
});
};
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
14 changes: 9 additions & 5 deletions workspaces/server/src/routes/image/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,13 @@ app.get(
throw new HTTPException(501, { message: `Image format: ${resImgFormat} is not supported.` });
}

const origFileGlob = [path.resolve(IMAGES_PATH, `${reqImgId}`), path.resolve(IMAGES_PATH, `${reqImgId}.*`)];
const { height, width } = c.req.valid('query');

const origFileGlob = [
width && height && path.resolve(IMAGES_PATH, `${reqImgId}_${width}x${height}`),
path.resolve(IMAGES_PATH, `${reqImgId}`),
path.resolve(IMAGES_PATH, `${reqImgId}.*`),
].filter(Boolean) as string[];
const [origFilePath] = await globby(origFileGlob, { absolute: true, onlyFiles: true });
if (origFilePath == null) {
throw new HTTPException(404, { message: 'Not found.' });
Expand All @@ -100,7 +106,7 @@ app.get(
if (!isSupportedImageFormat(origImgFormat)) {
throw new HTTPException(500, { message: 'Failed to load image.' });
}
if (resImgFormat === origImgFormat && c.req.valid('query').width == null && c.req.valid('query').height == null) {
if (resImgFormat === origImgFormat && width == null && width == null) {
// 画像変換せずにそのまま返す
c.header('Content-Type', IMAGE_MIME_TYPE[resImgFormat]);
return c.body(createStreamBody(createReadStream(origFilePath)));
Expand All @@ -109,9 +115,7 @@ app.get(
const origBinary = await fs.readFile(origFilePath);
const image = new Image(await IMAGE_CONVERTER[origImgFormat].decode(origBinary));

const reqImageSize = c.req.valid('query');

const scale = Math.max((reqImageSize.width ?? 0) / image.width, (reqImageSize.height ?? 0) / image.height) || 1;
const scale = Math.max((width ?? 0) / image.width, (height ?? 0) / image.height) || 1;
const manipulated = image.resize({
height: Math.ceil(image.height * scale),
preserveAspectRatio: true,
Expand Down
16 changes: 15 additions & 1 deletion workspaces/server/src/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import path from 'node:path';

import { serveStatic } from '@hono/node-server/serve-static';
import { Hono } from 'hono';
import { compress } from 'hono/compress';
import { cors } from 'hono/cors';
import { HTTPException } from 'hono/http-exception';
import { secureHeaders } from 'hono/secure-headers';

import { IMAGES_PATH } from '../constants/paths';
import { cacheControlMiddleware } from '../middlewares/cacheControlMiddleware';
import { compressMiddleware } from '../middlewares/compressMiddleware';

Expand All @@ -11,7 +16,6 @@ import { apiApp } from './api';
import { imageApp } from './image';
import { ssrApp } from './ssr';
import { staticApp } from './static';

const app = new Hono();

app.use(secureHeaders());
Expand All @@ -24,12 +28,22 @@ app.use(
origin: (origin) => origin,
}),
);

app.use(compress());
app.use(compressMiddleware);
app.use(cacheControlMiddleware);

app.get('/healthz', (c) => {
return c.body('live', 200);
});
app.use(
'/raw-images/*',
serveStatic({
onNotFound: (p) => console.log(path.relative(process.cwd(), IMAGES_PATH), p),
rewriteRequestPath: (path) => path.replace('/raw-images/', ''),
root: path.relative(process.cwd(), IMAGES_PATH),
}),
);
app.route('/', staticApp);
app.route('/', imageApp);
app.route('/', apiApp);
Expand Down

0 comments on commit 0cf8ce7

Please sign in to comment.