/** * 图片工具函数 * 提供图片 URL 选择、格式检测等实用功能 */ import { PostImageDTO } from '../types'; /** * 图片显示模式 */ export type ImageDisplayMode = 'list' | 'grid' | 'detail'; /** * 根据显示模式获取预览图 URL * @param image 图片对象 * @param mode 显示模式 * @returns 图片 URL */ export function getPreviewImageUrl(image: PostImageDTO, mode: ImageDisplayMode): string { // 如果没有预览图,返回原图 if (!image) { return ''; } switch (mode) { case 'list': case 'grid': // 列表和网格模式使用普通预览图 return image.preview_url || image.url || ''; case 'detail': // 详情页使用大预览图 return image.preview_url_large || image.preview_url || image.url || ''; default: return image.url || ''; } } /** * 检测 WebP 支持并构建 Accept header * @returns Accept header 字符串 */ export function getImageAcceptHeader(): string { // 检测浏览器是否支持 WebP // 如果支持,优先请求 WebP return 'image/webp,image/apng,image/*,*/*;q=0.8'; } /** * 判断是否应该使用预览图 * @param mode 显示模式 * @param hasPreview 是否有预览图 * @returns 是否使用预览图 */ export function shouldUsePreview(mode: ImageDisplayMode, hasPreview: boolean): boolean { // 列表和网格模式优先使用预览图 if (mode === 'list' || mode === 'grid') { return hasPreview; } // 详情页也使用预览图,但点击后加载原图 if (mode === 'detail') { return hasPreview; } return false; } /** * 从图片 URL 提取文件扩展名 * @param url 图片 URL * @returns 文件扩展名(如 '.jpg') */ export function getImageExtension(url: string): string { if (!url) return ''; try { const urlObj = new URL(url); const pathname = urlObj.pathname; const ext = pathname.match(/\.[0-9a-z]+$/i); return ext ? ext[0].toLowerCase() : ''; } catch { // 如果 URL 解析失败,直接从字符串匹配 const match = url.match(/\.[0-9a-z]+$/i); return match ? match[0].toLowerCase() : ''; } } /** * 判断是否是 GIF 图片 * @param url 图片 URL * @returns 是否是 GIF */ export function isGifImage(url: string): boolean { return getImageExtension(url) === '.gif'; } /** * 判断是否是 WebP 图片 * @param url 图片 URL * @returns 是否是 WebP */ export function isWebPImage(url: string): boolean { return getImageExtension(url) === '.webp'; }