
Published on June 27, 2025 by Eunbi.N
Skeleton UI Loading UX Performance UI Design
Google Vision API: 클라우드 기반 고성능 OCR



const onFileChange = async ($event: Event) => {
isProcessing.value = true;
const file = ($event.target as HTMLInputElement).files?.[0];
const base64 = await toBase64(file as File);
const imageContent = (base64 as string).replace(/^data:image\/(png|jpeg);base64,/, '');
const requestBody = {
requests: [
{
image: { content: imageContent },
features: [{ type: 'TEXT_DETECTION' }],
},
],
};
const response = await axios.post(
`https://vision.googleapis.com/v1/images:annotate?key=${API_VISION_KEY}`,
requestBody
);
ocrText.value = response.data?.responses?.[0]?.fullTextAnnotation?.text?.trim() ?? '';
if (!ocrText.value || ocrText.value === '') return;
await extractWithLLM(ocrText.value);
isProcessing.value = false;
};
const toBase64 = (file: File) =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
async function extractWithLLM(rawText: string) {
const prompt = PROMPT(rawText);
const declarationIsNonDoc = ['비서류용', 'Non-Document'].includes(rawText);
emsInfo.value.customsDeclaration.category = declarationIsNonDoc ? 'DOCUMENT' : 'GIFT';
//rawText 에서 서류용인지 비서류용인지 체크 (디폴트 : 비서류)
const declarationType =
emsInfo.value.customsDeclaration.category === 'DOCUMENT' ? 'declaration-doc' : 'declaration-non-doc';
try {
const response = await fetch('https://api.groq.com/openai/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${API_GROQ_KEY}`,
},
body: JSON.stringify({
model: 'llama3-70b-8192',
messages: [
{ role: 'system', content: 'You are a helpful assistant that extracts structured data from OCR' },
{ role: 'user', content: prompt },
],
temperature: 0.2,
}),
});
const data = await response.json();
const content = data.choices?.[0]?.message?.content || '{}';
const parsedContent = content.match(/```(?:json)?\s*([\s\S]*?)\s*```/)[1];
const parsedContentJson = JSON.parse(parsedContent);
emsInfo.value = { ... parsedContentJson };
} catch (e) {
console.error(e);
}
}
Image Enhancement: 이미지 품질 개선
Raw Processing: 원본 이미지 직접 처리
Text Extraction: 순수 텍스트 추출
Structured Data: 구조화된 데이터 추출
Batch Processing: 대량 이미지 일괄 처리
Real-time Processing: 즉시 처리와 피드백