feat: add some shit

This commit is contained in:
max_richter 2023-08-02 02:51:20 +02:00
parent 3dc9692eef
commit 32b6b04eb9
3 changed files with 47 additions and 12 deletions

BIN
image.jpg Normal file

Binary file not shown.

21
lib/cache/image.ts vendored
View File

@ -1,5 +1,6 @@
import { hash } from "@lib/hash.ts";
import * as cache from "@lib/cache/cache.ts";
import { ImageMagick } from "https://deno.land/x/imagemagick_deno@0.0.25/mod.ts";
type ImageCacheOptions = {
url: string;
@ -19,6 +20,20 @@ function getCacheKey({ url: _url, width, height }: ImageCacheOptions) {
);
}
function verifyImage(
imageBuffer: Uint8Array,
) {
return new Promise<boolean>((resolve) => {
try {
ImageMagick.read(imageBuffer, (image) => {
resolve(image.height !== 0 && image.width !== 0);
});
} catch (_err) {
resolve(false);
}
});
}
export async function getImage({ url, width, height }: ImageCacheOptions) {
const cacheKey = getCacheKey({ url, width, height });
@ -44,6 +59,12 @@ export async function setImage(
) {
const clone = new Uint8Array(buffer);
const imageCorrect = await verifyImage(clone);
if (!imageCorrect) {
console.log("[cache/image] failed to store image", { url });
return;
}
const cacheKey = getCacheKey({ url, width, height });
const pointerId = await hash(cacheKey);

View File

@ -2,8 +2,10 @@ import { HandlerContext, Handlers } from "$fresh/server.ts";
import {
ImageMagick,
initialize,
MagickFormat,
MagickGeometry,
} from "https://deno.land/x/imagemagick_deno@0.0.25/mod.ts";
import { parseMediaType } from "https://deno.land/std@0.175.0/media_types/parse_media_type.ts";
import * as cache from "@lib/cache/image.ts";
import { SILVERBULLET_SERVER } from "@lib/env.ts";
@ -49,10 +51,21 @@ function getWidthHeight(
function modifyImage(
imageBuffer: Uint8Array,
params: { width: number; height: number; mode: "resize" | "crop" },
params: {
width: number;
mediaType: string;
height: number;
mode: "resize" | "crop";
},
) {
return new Promise<Uint8Array>((resolve) => {
ImageMagick.read(imageBuffer, (image) => {
let format = MagickFormat.Jpeg;
if (params.mediaType === "image/webp") {
format = MagickFormat.Webp;
}
ImageMagick.read(imageBuffer, format, (image) => {
const sizingData = getWidthHeight(image, params);
if (params.mode === "resize") {
image.resize(sizingData);
@ -100,6 +113,7 @@ async function processImage(imageUrl: string, params: ImageParams) {
const modifiedImage = await modifyImage(remoteImage.buffer, {
...params,
mediaType: remoteImage.mediaType,
mode: "resize",
});
@ -108,13 +122,6 @@ async function processImage(imageUrl: string, params: ImageParams) {
length: modifiedImage.length,
});
await cache.setImage(modifiedImage.slice(), {
url: imageUrl,
width: params.width,
height: params.height,
mediaType: remoteImage.mediaType,
});
return [modifiedImage, remoteImage.mediaType] as const;
}
@ -131,15 +138,13 @@ const GET = async (
const imageUrl = SILVERBULLET_SERVER + "/" + params.image;
console.log("[api/image] " + imageUrl);
const cachedResponse = await cache.getImage({
url: imageUrl,
width: params.width,
height: params.height,
});
if (cachedResponse) {
console.log("[api/image] got cached image");
console.log("[api/image] cached: " + imageUrl);
return new Response(cachedResponse.buffer.slice(), {
headers: {
"Content-Type": cachedResponse.mediaType,
@ -153,6 +158,15 @@ const GET = async (
processImage(imageUrl, params)
);
cache.setImage(resizedImage.slice(), {
url: imageUrl,
width: params.width,
height: params.height,
mediaType: mediaType,
});
console.log("[api/image] not-cached: " + imageUrl);
return new Response(resizedImage, {
headers: {
"Content-Type": mediaType,