perf: serve aliyun oss previews directly
This commit is contained in:
parent
e1e4c205e1
commit
a6083ac409
@ -72,11 +72,13 @@ async function loadImage(url: string) {
|
||||
width: MERGED_IMAGE_MAX_WIDTH,
|
||||
quality: 92,
|
||||
format: "png",
|
||||
delivery: "proxy",
|
||||
}),
|
||||
buildImageProxyUrl(normalizedSource, {
|
||||
width: Math.min(MERGED_IMAGE_MAX_WIDTH, 960),
|
||||
quality: 86,
|
||||
format: "webp",
|
||||
delivery: "proxy",
|
||||
}),
|
||||
normalizedSource,
|
||||
].filter((item): item is string => Boolean(item))
|
||||
|
||||
@ -2742,7 +2742,10 @@ export function AgentPsdTemplateEditorDialog({
|
||||
|
||||
const fetchCandidates = Array.from(
|
||||
new Set(
|
||||
[normalizedUrl, buildImageProxyUrl(normalizedUrl)].filter(Boolean)
|
||||
[
|
||||
normalizedUrl,
|
||||
buildImageProxyUrl(normalizedUrl, { delivery: "proxy" }),
|
||||
].filter(Boolean)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@ -1055,7 +1055,9 @@ export function AgentPsdTemplateExportPreview({
|
||||
try {
|
||||
setIsDownloading(true);
|
||||
if (!shouldCompose) {
|
||||
const response = await fetch(buildImageProxyUrl(imageUrl));
|
||||
const response = await fetch(
|
||||
buildImageProxyUrl(imageUrl, { delivery: "proxy" })
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(`下载失败(${response.status})`);
|
||||
}
|
||||
@ -1066,7 +1068,7 @@ export function AgentPsdTemplateExportPreview({
|
||||
}
|
||||
|
||||
const { image, dispose } = await loadImageFromCandidates([
|
||||
buildImageProxyUrl(imageUrl),
|
||||
buildImageProxyUrl(imageUrl, { delivery: "proxy" }),
|
||||
imageUrl,
|
||||
]);
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ async function drawMarkerOnImage(
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
img.crossOrigin = 'anonymous';
|
||||
const loadUrl = buildImageProxyUrl(imageUrl);
|
||||
const loadUrl = buildImageProxyUrl(imageUrl, { delivery: "proxy" });
|
||||
|
||||
img.onload = () => {
|
||||
// 创建 canvas
|
||||
|
||||
@ -1113,7 +1113,7 @@ export function RealtimeCanvasDialog({
|
||||
return new Promise<HTMLImageElement>((resolve, reject) => {
|
||||
const image = new Image();
|
||||
const resolvedSrc = /^https?:\/\//i.test(src)
|
||||
? buildImageProxyUrl(src)
|
||||
? buildImageProxyUrl(src, { delivery: "proxy" })
|
||||
: src;
|
||||
image.crossOrigin = "anonymous";
|
||||
image.onload = () => resolve(image);
|
||||
|
||||
@ -334,7 +334,7 @@ async function drawMarkerOnImage(
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
img.crossOrigin = "anonymous";
|
||||
const loadUrl = buildImageProxyUrl(imageUrl);
|
||||
const loadUrl = buildImageProxyUrl(imageUrl, { delivery: "proxy" });
|
||||
|
||||
img.onload = () => {
|
||||
const canvas = document.createElement("canvas");
|
||||
|
||||
@ -108,7 +108,7 @@ export function ImageAnnotator({
|
||||
(submitMode === "publish-new-canvas" ? "发布到新的画布" : "发送到新对话");
|
||||
const forceDarkAppearance = appearance === "dark";
|
||||
const toCanvasLoadUrl = useCallback((url: string) => {
|
||||
return buildImageProxyUrl(url);
|
||||
return buildImageProxyUrl(url, { delivery: "proxy" });
|
||||
}, []);
|
||||
|
||||
const revokeObjectUrl = useCallback(() => {
|
||||
|
||||
@ -6,6 +6,7 @@ export type ImageProxyOptions = {
|
||||
width?: number;
|
||||
quality?: number;
|
||||
format?: ImageProxyFormat;
|
||||
delivery?: "display" | "proxy";
|
||||
};
|
||||
|
||||
function clamp(value: number, min: number, max: number): number {
|
||||
@ -36,12 +37,70 @@ function isBypassUrl(url: string): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
function isAliyunOssImageHost(hostname: string): boolean {
|
||||
const normalized = hostname.trim().toLowerCase();
|
||||
return normalized.endsWith(".aliyuncs.com") && normalized.includes(".oss-");
|
||||
}
|
||||
|
||||
function resolveAliyunOssDisplayUrl(
|
||||
url: string,
|
||||
options: Pick<ImageProxyOptions, "width" | "quality" | "format">
|
||||
): string | null {
|
||||
let target: URL;
|
||||
try {
|
||||
target = new URL(url);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isAliyunOssImageHost(target.hostname)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (target.searchParams.has("x-oss-process")) {
|
||||
return target.toString();
|
||||
}
|
||||
|
||||
const width = normalizeWidth(options.width);
|
||||
const quality = normalizeQuality(options.quality);
|
||||
const format = options.format;
|
||||
|
||||
if (!width && !quality && !format) {
|
||||
return target.toString();
|
||||
}
|
||||
|
||||
const processSteps = ["image"];
|
||||
if (width) {
|
||||
processSteps.push(`resize,w_${width}`);
|
||||
}
|
||||
if (quality) {
|
||||
processSteps.push(`quality,q_${quality}`);
|
||||
}
|
||||
if (format) {
|
||||
const ossFormat = format === "jpeg" ? "jpg" : format;
|
||||
if (ossFormat !== "webp" && ossFormat !== "jpg" && ossFormat !== "png") {
|
||||
return null;
|
||||
}
|
||||
processSteps.push(`format,${ossFormat}`);
|
||||
}
|
||||
|
||||
target.searchParams.set("x-oss-process", processSteps.join("/"));
|
||||
return target.toString();
|
||||
}
|
||||
|
||||
export function buildImageProxyUrl(url: string, options: ImageProxyOptions = {}): string {
|
||||
const source = String(url || "").trim();
|
||||
if (isBypassUrl(source)) {
|
||||
return source;
|
||||
}
|
||||
|
||||
if (options.delivery !== "proxy") {
|
||||
const directDisplayUrl = resolveAliyunOssDisplayUrl(source, options);
|
||||
if (directDisplayUrl) {
|
||||
return directDisplayUrl;
|
||||
}
|
||||
}
|
||||
|
||||
const width = normalizeWidth(options.width);
|
||||
const quality = normalizeQuality(options.quality);
|
||||
const format = options.format;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user