UNPKG

vuepress-plugin-photomap

Version:

VuePress2插件,用于在文章中插入照片地图组件,类似Apple相册的PhotoMap功能

126 lines (125 loc) 4.32 kB
import { ref } from 'vue'; export function useExifReader() { const loading = ref(false); const error = ref(null); // 从图片提取EXIF数据 const extractExifData = async (img) => { try { // 使用现代的exifr库 const exifr = await import('exifr'); const exifrLib = exifr.default || exifr; // 从图片中读取GPS和基本EXIF数据 const exifData = await exifrLib.parse(img, { gps: true, orientation: true, tiff: true, ifd0: true, exif: true }); return exifData || {}; } catch (err) { console.error('EXIF数据解析失败:', err); return {}; } }; // 解析GPS坐标 const parseGPSData = (exifData) => { // exifr库直接返回十进制度数,不需要转换 const latitude = exifData?.latitude || exifData?.GPSLatitude; const longitude = exifData?.longitude || exifData?.GPSLongitude; if (typeof latitude !== 'number' || typeof longitude !== 'number') { return null; } // 验证坐标有效性 if (latitude < -90 || latitude > 90 || longitude < -180 || longitude > 180) { return null; } const gpsData = { latitude, longitude }; // 可选的GPS数据 const altitude = exifData?.altitude || exifData?.GPSAltitude; if (typeof altitude === 'number') { gpsData.altitude = altitude; } const direction = exifData?.GPSImgDirection; if (typeof direction === 'number') { gpsData.direction = direction; } return gpsData; }; // 加载单张图片的EXIF数据 const loadImageExif = async (src, alt = '') => { return new Promise((resolve) => { const img = new Image(); img.crossOrigin = 'anonymous'; const photoData = { src, alt, hasGPS: false }; img.onload = async () => { try { // 获取图片尺寸 photoData.width = img.naturalWidth; photoData.height = img.naturalHeight; // 提取EXIF数据 const exifData = await extractExifData(img); // 解析GPS数据 const gpsData = parseGPSData(exifData); if (gpsData) { photoData.gps = gpsData; photoData.hasGPS = true; } else { photoData.error = '该图片不包含GPS位置信息'; } } catch (err) { photoData.error = '解析EXIF数据时出错'; console.warn('EXIF解析错误:', err); } resolve(photoData); }; img.onerror = () => { photoData.error = '图片加载失败'; resolve(photoData); }; img.src = src; }); }; // 批量处理多张图片 const loadImagesExif = async (images) => { loading.value = true; error.value = null; try { const promises = images.map(img => loadImageExif(img.src, img.alt)); const results = await Promise.all(promises); // 统计有GPS信息的图片数量 const gpsCount = results.filter(r => r.hasGPS).length; if (gpsCount === 0) { error.value = '所有图片都不包含GPS位置信息'; } else if (gpsCount < images.length) { console.warn(`${images.length - gpsCount} 张图片缺少GPS信息`); } return results; } catch (err) { error.value = '处理图片EXIF数据时出错'; console.error('批量EXIF处理错误:', err); return []; } finally { loading.value = false; } }; return { loading, error, loadImageExif, loadImagesExif }; }