fix: images in remotes
All checks were successful
Deploy to SFTP Server / build (push) Successful in 9m22s
All checks were successful
Deploy to SFTP Server / build (push) Successful in 9m22s
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
---
|
||||
import type { ImageMetadata } from "astro";
|
||||
import { Picture as AstroImage } from "astro:assets";
|
||||
import { inferRemoteSize } from 'astro/assets/utils';
|
||||
import { generateThumbHash, getExifData } from "@helpers/image";
|
||||
import sharp from "sharp";
|
||||
interface Props {
|
||||
@@ -14,14 +15,16 @@ interface Props {
|
||||
maxWidth?: number;
|
||||
}
|
||||
|
||||
async function checkImage(src: string) {
|
||||
async function checkImage(image: ImageMetadata) {
|
||||
const src = image.src;
|
||||
try {
|
||||
if (src.startsWith("/@fs") || src.startsWith("/_astro")) return true;
|
||||
const res = await sharp(src).metadata();
|
||||
const res = await inferRemoteSize(src);
|
||||
if (res.format) {
|
||||
image.format = res.format;
|
||||
return true;
|
||||
}else {
|
||||
console.log("Failed to fetch: ", src);
|
||||
console.log("Failed to load: ", src);
|
||||
}
|
||||
return false;
|
||||
} catch (err) {
|
||||
@@ -39,8 +42,8 @@ const {
|
||||
maxWidth,
|
||||
} = Astro.props;
|
||||
|
||||
let thumbhash = hash && image.fsPath ? await generateThumbHash(image) : "";
|
||||
const imageOk = await checkImage(image.src);
|
||||
let thumbhash = hash && await generateThumbHash(image);
|
||||
const imageOk = await checkImage(image);
|
||||
|
||||
let exif = imageOk && (await getExifData(image));
|
||||
|
||||
@@ -81,5 +84,5 @@ const sizes = [
|
||||
.join(", ")}>
|
||||
<slot />
|
||||
</AstroImage>
|
||||
) : "Image not ok"
|
||||
) : undefined
|
||||
}
|
||||
|
||||
@@ -8,11 +8,32 @@ export async function generateThumbHash(
|
||||
) {
|
||||
const scaleFactor = 100 / Math.max(image.width, image.height);
|
||||
|
||||
const smallWidth = Math.floor(image.width * scaleFactor);
|
||||
const smallHeight = Math.floor(image.height * scaleFactor);
|
||||
let smallWidth = Math.floor(image.width * scaleFactor);
|
||||
let smallHeight = Math.floor(image.height * scaleFactor);
|
||||
|
||||
try {
|
||||
const smallImg = await sharp(image.fsPath)
|
||||
const imagePath = (image as ImageMetadata & { fsPath: string }).fsPath ??
|
||||
image.src;
|
||||
|
||||
let sp;
|
||||
if (imagePath.startsWith("https://") || imagePath.startsWith("http://")) {
|
||||
const res = await fetch(imagePath);
|
||||
if (!res.ok) {
|
||||
return;
|
||||
}
|
||||
sp = sharp(await res.arrayBuffer());
|
||||
} else {
|
||||
sp = sharp(imagePath);
|
||||
}
|
||||
|
||||
if (!smallWidth || !smallHeight) {
|
||||
const meta = await sp.metadata();
|
||||
const scaleFactor = 100 / Math.max(meta.width, meta.height);
|
||||
smallWidth = Math.floor(meta.width * scaleFactor);
|
||||
smallHeight = Math.floor(meta.height * scaleFactor);
|
||||
}
|
||||
|
||||
const smallImg = await sp
|
||||
.resize(smallWidth, smallHeight)
|
||||
.withMetadata()
|
||||
.raw()
|
||||
@@ -22,7 +43,10 @@ export async function generateThumbHash(
|
||||
const buffer = rgbaToThumbHash(smallWidth, smallHeight, smallImg);
|
||||
return Buffer.from(buffer).toString("base64");
|
||||
} catch (error) {
|
||||
console.log(`Could not generate thumbhash for ${image.fsPath}`, error);
|
||||
console.log(
|
||||
`Could not generate thumbhash for ${image.fsPath ?? image.src}`,
|
||||
error,
|
||||
);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -45,9 +69,17 @@ const allowedExif = [
|
||||
|
||||
export async function getExifData(image: ImageMetadata) {
|
||||
if (image.format === "svg") return undefined; // SVGs don't have EXIF data")
|
||||
const imagePath = (image as ImageMetadata & { fsPath: string }).fsPath;
|
||||
const imagePath = (image as ImageMetadata & { fsPath: string }).fsPath ??
|
||||
image.src;
|
||||
|
||||
try {
|
||||
const buffer = await sharp(imagePath).toBuffer();
|
||||
let buffer: ArrayBuffer;
|
||||
if (imagePath.startsWith("https://") || imagePath.startsWith("http://")) {
|
||||
const res = await fetch(imagePath);
|
||||
buffer = await res.arrayBuffer();
|
||||
} else {
|
||||
buffer = await sharp(imagePath).toBuffer() as unknown as ArrayBuffer;
|
||||
}
|
||||
|
||||
const tags = await ExifReader.load(buffer, { async: true });
|
||||
|
||||
@@ -62,7 +94,7 @@ export async function getExifData(image: ImageMetadata) {
|
||||
|
||||
return hasExif ? out : undefined;
|
||||
} catch (error) {
|
||||
console.log(`Error reading EXIF data from ${imagePath}`, error);
|
||||
console.log(`Error reading EXIF data from ${JSON.stringify(image)}`, error);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import Layout from "@layouts/Layout.astro";
|
||||
import HeroCard from "@components/HeroCard.astro";
|
||||
import * as memorium from "@helpers/memorium";
|
||||
import { resources as resourceTypes } from "../resources.ts";
|
||||
import markdownToText from "@helpers/markdownToText";
|
||||
|
||||
const { resourceType } = Astro.params;
|
||||
|
||||
@@ -10,7 +11,7 @@ async function safeGetResource(resType) {
|
||||
try {
|
||||
return await memorium.listResource(resourceType);
|
||||
} catch (error) {
|
||||
return {content:[]};
|
||||
return { content: [] };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +27,19 @@ export async function getStaticPaths() {
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getImageUrl(input: string): string {
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
if (input.startsWith("https://") || input.startsWith("http://")) {
|
||||
return input;
|
||||
}
|
||||
if (input.startsWith("/")) {
|
||||
return `https://marka.max-richter.dev${input}`;
|
||||
}
|
||||
return `https://marka.max-richter.dev/${input}`;
|
||||
}
|
||||
---
|
||||
|
||||
<Layout title="Max Richter">
|
||||
@@ -40,7 +54,7 @@ export async function getStaticPaths() {
|
||||
data: {
|
||||
title: resource.content.name,
|
||||
cover: {
|
||||
src: `https://marka.max-richter.dev/${resource.content.image}`,
|
||||
src: getImageUrl(resource.content.image),
|
||||
},
|
||||
},
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user