Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | 1x 1x 1x 1x 1x | import { IMAGE_CONFIG } from './constants/image';
export const validateImage = async (file: File): Promise<{ valid: boolean; error?: string }> => {
// 1. 확장자 검증
const fileName = file.name.toLowerCase();
const hasValidExtension = IMAGE_CONFIG.allowedExtensions.some((ext) => fileName.endsWith(ext));
if (!hasValidExtension) {
return {
valid: false,
error: `파일 확장자가 올바르지 않습니다. \n(${IMAGE_CONFIG.allowedExtensions.join(', ')}만 가능)`,
};
}
// 2. 파일 크기 검증
if (file.size > IMAGE_CONFIG.maxSizeBytes) {
const currentSizeMB = (file.size / (1024 * 1024)).toFixed(0);
return {
valid: false,
error: `이미지 크기가 너무 큽니다. 최대 20MB까지 가능합니다. \n현재: ${currentSizeMB}MB`,
};
}
// 3. 파일 사이즈 검증
const { width, height } = await getImageDimensions(file);
if (width > IMAGE_CONFIG.maxWidth || height > IMAGE_CONFIG.maxHeight) {
return {
valid: false,
error: `이미지는 ${IMAGE_CONFIG.maxWidth}x${IMAGE_CONFIG.maxHeight} 이하여야 합니다. \n현재: 너비(${width}), 높이(${height})`,
};
}
return { valid: true };
};
const getImageDimensions = async (file: File): Promise<{ width: number; height: number }> => {
return new Promise((resolve, reject) => {
const img = new Image();
const url = URL.createObjectURL(file);
img.onload = () => {
URL.revokeObjectURL(url); // 메모리 해제
resolve({
width: img.width,
height: img.height,
});
};
img.onerror = () => {
URL.revokeObjectURL(url);
reject(new Error('이미지 로드 실패'));
};
img.src = url;
});
};
|