You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
3.8 KiB
146 lines
3.8 KiB
|
4 weeks ago
|
/**
|
||
|
|
* 图片处理工具函数
|
||
|
|
* 支持外部 URL(HTTP/HTTPS 和 Data URI)和本地路径(/images/...)
|
||
|
|
*
|
||
|
|
* 本地路径格式:/images/game/{typeName}/{color|dark|light}_{play_id}.png
|
||
|
|
* 例如:/images/game/chess/color_101.png
|
||
|
|
*
|
||
|
|
* 注意:React Native 中不支持本地文件路径的动态 require()
|
||
|
|
* 本地路径会被 Expo 的静态资源服务器处理
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 判断是否为有效的外部 URL
|
||
|
|
* @param source 图片源
|
||
|
|
* @returns 是否为有效的外部 URL
|
||
|
|
*/
|
||
|
|
export const isExternalUrl = (source: string | undefined): boolean => {
|
||
|
|
if (!source) return false;
|
||
|
|
return /^https?:\/\//.test(source) || /^data:image\//.test(source);
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 判断是否为本地路径
|
||
|
|
* @param source 图片源
|
||
|
|
* @returns 是否为本地路径
|
||
|
|
*/
|
||
|
|
export const isLocalPath = (source: string | undefined): boolean => {
|
||
|
|
if (!source) return false;
|
||
|
|
return /^\/images\//.test(source);
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 获取图片 URI
|
||
|
|
*
|
||
|
|
* 验证并返回有效的图片 URI
|
||
|
|
* 支持外部 URL(HTTP/HTTPS 和 Data URI)和本地路径(/images/...)
|
||
|
|
*
|
||
|
|
* @param source 图片源(URL 或本地路径)
|
||
|
|
* @returns 有效的图片 URI,如果无效返回 undefined
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```typescript
|
||
|
|
* // 外部 URL
|
||
|
|
* const uri = getImageSource('https://example.com/image.png');
|
||
|
|
* // 返回: 'https://example.com/image.png'
|
||
|
|
*
|
||
|
|
* // Data URI
|
||
|
|
* const uri = getImageSource('data:image/png;base64,iVBORw0KGgo...');
|
||
|
|
* // 返回: 'data:image/png;base64,iVBORw0KGgo...'
|
||
|
|
*
|
||
|
|
* // 本地路径
|
||
|
|
* const uri = getImageSource('/images/game/chess/color_101.png');
|
||
|
|
* // 返回: '/images/game/chess/color_101.png'
|
||
|
|
*
|
||
|
|
* // 无效的 URL
|
||
|
|
* const uri = getImageSource('invalid-url');
|
||
|
|
* // 返回: undefined
|
||
|
|
* ```
|
||
|
|
*/
|
||
|
|
export const getImageSource = (source: string | undefined): string | undefined => {
|
||
|
|
if (!source) return undefined;
|
||
|
|
|
||
|
|
// 支持外部 URL
|
||
|
|
if (isExternalUrl(source)) {
|
||
|
|
return source;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 支持本地路径
|
||
|
|
if (isLocalPath(source)) {
|
||
|
|
return source;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 其他格式不支持
|
||
|
|
return undefined;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 将本地路径转换为可用的 require 对象
|
||
|
|
*
|
||
|
|
* 在 React Native 中,本地资源必须使用 require() 加载
|
||
|
|
* 这个函数使用预定义的图片映射表来获取资源
|
||
|
|
*
|
||
|
|
* @param localPath 本地路径,例如 /images/game/chess/color_101.png
|
||
|
|
* @returns require 对象,如果路径无效返回 undefined
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```typescript
|
||
|
|
* const source = convertLocalPathToUri('/images/game/chess/color_101.png');
|
||
|
|
* // 返回: require('../assets/images/game/chess/color_101.png')
|
||
|
|
* ```
|
||
|
|
*/
|
||
|
|
export const convertLocalPathToUri = (localPath: string): any => {
|
||
|
|
if (!localPath || !isLocalPath(localPath)) {
|
||
|
|
return undefined;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
// 使用图片映射表获取本地资源
|
||
|
|
const { getGameImageFromPath } = require('@/constants/gameImages');
|
||
|
|
return getGameImageFromPath(localPath);
|
||
|
|
} catch (error) {
|
||
|
|
// 如果获取失败,返回 undefined
|
||
|
|
if (__DEV__) {
|
||
|
|
console.warn(`Failed to load image: ${localPath}`, error);
|
||
|
|
}
|
||
|
|
return undefined;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 获取图片源(带默认值)
|
||
|
|
*
|
||
|
|
* 如果主图片 URL 无效,返回默认图片 URL
|
||
|
|
*
|
||
|
|
* @param source 图片源(URL)
|
||
|
|
* @param defaultSource 默认图片源(URL)
|
||
|
|
* @returns 有效的图片 URI
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```typescript
|
||
|
|
* // 如果主图片无效,使用默认图片
|
||
|
|
* const uri = getImageSourceWithDefault(
|
||
|
|
* item.imageUrl,
|
||
|
|
* 'https://via.placeholder.com/200'
|
||
|
|
* );
|
||
|
|
* ```
|
||
|
|
*/
|
||
|
|
export const getImageSourceWithDefault = (
|
||
|
|
source: string | undefined,
|
||
|
|
defaultSource: string
|
||
|
|
): string | undefined => {
|
||
|
|
const imageSource = getImageSource(source);
|
||
|
|
if (imageSource) {
|
||
|
|
return imageSource;
|
||
|
|
}
|
||
|
|
return getImageSource(defaultSource);
|
||
|
|
};
|
||
|
|
|
||
|
|
export default {
|
||
|
|
getImageSource,
|
||
|
|
getImageSourceWithDefault,
|
||
|
|
isExternalUrl,
|
||
|
|
isLocalPath,
|
||
|
|
convertLocalPathToUri,
|
||
|
|
};
|