Chrome Built-in AI — LanguageModel API로 이미지에서 텍스트 추출하기
Chrome의 LanguageModel API를 사용해 서버 없이 브라우저에서 이미지 OCR을 구현하는 방법과 실제 테스트 결과를 정리한다.
브라우저에서 이미지 속 글자를 읽는다
Tesseract.js나 Google Vision API 없이, 브라우저 자체 AI로 이미지에서 텍스트를 뽑아낼 수 있다. Chrome의 LanguageModel API는 이미지를 입력으로 받아 텍스트를 출력할 수 있는 멀티모달 API다.
외부 서버가 없다. API 키도 없다. Chrome 브라우저와 플래그 설정 하나로 동작한다.
[💡 잠깐! 이 용어는?]
LanguageModel API (Prompt API): window.LanguageModel로 접근하는 Chrome Built-in AI API. Gemini Nano를 직접 호출해 텍스트 생성, 분류, 추출 작업을 수행한다. 이미지 입력도 지원해 멀티모달 추론이 가능하다.
준비: Chrome 플래그 활성화
LanguageModel API는 아직 실험 단계다. Chrome 주소창에서 아래 플래그를 활성화해야 한다.
chrome://flags/#prompt-api-for-gemini-nano
Enabled로 설정 후 Chrome 재시작. 이미지 입력을 쓰려면 추가로:
chrome://flags/#optimization-guide-on-device-model
도 Enabled로 설정한다. 모델이 로컬에 없으면 첫 실행 시 자동 다운로드된다.
기본 세션 생성
이미지를 입력으로 사용하려면 세션 생성 시 expectedInputs에 image 타입을 명시해야 한다.
async function createOcrSession() {
const available = await LanguageModel.availability({
expectedInputs: [{ type: 'image' }],
});
if (available === 'unavailable') {
throw new Error('이미지 지원 LanguageModel을 사용할 수 없습니다.');
}
const session = await LanguageModel.create({
expectedInputs: [{ type: 'image' }],
initialInputs: [
{
role: 'system',
content:
'당신은 이미지에서 텍스트를 추출하는 OCR 전문가입니다. 이미지에 보이는 텍스트를 정확하게 읽어주세요.',
},
],
});
return session;
}initialInputs의 system 메시지가 중요하다. "OCR 전문가"라는 역할을 명확히 주면 모델이 이미지 묘사보다 텍스트 추출에 집중한다.
텍스트만 추출하는 방법
가장 단순한 OCR이다. 이미지를 주고 텍스트만 받아온다.
async function extractText(imageFile) {
const session = await createOcrSession();
const result = await session.prompt([
{
role: 'user',
content: [
{
type: 'image',
value: imageFile,
},
{
type: 'text',
value: '이 이미지에서 텍스트를 전부 추출해주세요. 텍스트만 출력하고 다른 설명은 필요 없습니다.',
},
],
},
]);
return result;
}session.prompt()의 content 배열에 이미지(type: 'image')와 텍스트 지시(type: 'text')를 함께 넣는다. 이미지 파일은 File 객체나 Blob을 그대로 넘기면 된다.
JSON 스키마로 구조화된 응답 받기
텍스트만 추출하는 것 외에, **바운딩 박스(위치 정보)**를 함께 받을 수도 있다. responseConstraint에 JSON 스키마를 넘기면 구조화된 응답이 나온다.
const ocrSchema = {
type: 'object',
properties: {
text_blocks: {
type: 'array',
items: {
type: 'object',
properties: {
text: { type: 'string' },
bounding_box: {
type: 'object',
properties: {
x: { type: 'number' },
y: { type: 'number' },
width: { type: 'number' },
height: { type: 'number' },
},
required: ['x', 'y', 'width', 'height'],
},
},
required: ['text', 'bounding_box'],
},
},
},
required: ['text_blocks'],
};
async function extractTextWithBounds(imageFile) {
const session = await createOcrSession();
const result = await session.prompt(
[
{
role: 'user',
content: [
{ type: 'image', value: imageFile },
{
type: 'text',
value: '이미지에서 텍스트와 각 텍스트의 위치(바운딩 박스)를 JSON으로 반환해주세요.',
},
],
},
],
{
responseConstraint: ocrSchema,
}
);
return JSON.parse(result);
}[💡 잠깐! 이 용어는?] responseConstraint: LanguageModel API의 출력 형식을 JSON 스키마로 제약하는 옵션. 이 옵션이 있으면 모델이 반드시 지정된 스키마에 맞는 JSON을 반환한다. 자유 텍스트 대신 파싱 가능한 구조화된 데이터를 받을 수 있다.
실제 테스트 결과
두 가지 방식을 비교한 테스트 결과다.
| 항목 | 텍스트만 추출 | JSON + 바운딩 박스 |
|---|---|---|
| 텍스트 정확도 | 높음 | 중간 |
| 위치 정보 | 없음 | 부정확 (근사값) |
| 처리 속도 | 빠름 | 느림 |
| 간판·표지판 | 잘 동작 | 동작하나 위치 오차 큼 |
| 밀집된 텍스트 | 누락 발생 | 더 많은 누락 |
바운딩 박스 테스트에서 중요한 점이 있다. 텍스트 자체는 잘 읽히는데, 좌표값이 실제 이미지 좌표와 다르다. Gemini Nano가 공간 추론에 최적화된 모델이 아니기 때문이다.
비유하면 책을 읽을 수 있는 사람에게 "이 페이지의 3번째 단어가 몇 번째 줄 몇 번째 칸에 있어?"라고 물어보는 것과 같다. 단어 자체는 읽지만 정확한 픽셀 좌표를 계산하는 건 다른 능력이다.
실용적으로는 텍스트만 추출하는 방식이 더 신뢰할 수 있다.
적합한 케이스
잘 동작하는 경우:
- 간판, 표지판, 현수막처럼 큰 글씨
- 스크린샷에 있는 UI 텍스트
- 명함, 영수증처럼 구조가 단순한 문서
- 단일 언어로 작성된 이미지
동작이 불안정한 경우:
- 손글씨
- 텍스트가 배경에 묻히는 경우 (저콘트라스트)
- 이미지 내 표·그래프 속 숫자
- 여러 언어가 섞인 이미지
브라우저 지원 현황
| 브라우저 | 지원 여부 | 비고 |
|---|---|---|
| Chrome 127+ | ✅ (플래그 필요) | 실험적 기능 |
| Chrome Stable | 🔜 | 안정화 진행 중 |
| Firefox | ❌ | 미지원 |
| Safari | ❌ | 미지원 |
| Edge | 🔜 | Chromium 기반, 향후 지원 예정 |
현재는 Chrome 개발자 도구를 쓰는 개발자나 프로토타이핑 단계에 적합하다. 프로덕션 서비스에 쓰려면 플래그 없이도 동작하는 stable 릴리즈를 기다려야 한다.
정리
- Chrome
LanguageModel.create({ expectedInputs: [{ type: 'image' }] })로 이미지 입력이 가능한 세션을 만들 수 있다. session.prompt()에 이미지 파일과 텍스트 지시를 함께 넣으면 OCR이 동작한다.responseConstraint로 JSON 스키마를 지정하면 구조화된 응답을 받을 수 있다.- 텍스트 추출 자체는 간판·표지판 수준에서 잘 동작한다. 바운딩 박스 좌표는 부정확하다.
- 현재는 Chrome 플래그 활성화가 필요한 실험 기능이다.
서버 없이 브라우저에서만 동작하는 OCR이 필요한 상황 — 내부 도구, 오프라인 앱, 프라이버시가 중요한 서비스 — 에서 충분히 실험해볼 만하다.
참고:
- Raymond Camden — Testing OCR with Chrome Built-in AI: https://www.raymondcamden.com/2026/04/11/testing-ocr-with-chrome-built-in-ai
- Chrome AI Built-in APIs: https://developer.chrome.com/docs/ai/built-in
- LanguageModel API 명세: https://github.com/webmachinelearning/writing-assistance-apis
이 시리즈의 다른 글
제목 앞부분이 같은 글 — 묶어 읽으면 흐름이 잡힌다
같은 카테고리 · Tooling
비슷한 주제의 최신 글
태그가 겹치는 글
공통 태그가 많을수록 위에 보인다