blog

๐ŸŒŸ ํ”„๋ŸฐํŠธ์—”๋“œ ํŽ˜์ด์ง• ๋กœ๋”ฉ / ์ง€์—ฐ ๋กœ๋”ฉ ๋ฏธ๋ฆฌ๋ณด๊ธฐ PDF ๐ŸŒŸ

๋จธ๋ฆฌ๋ง ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ PDF๋ฅผ ๋ฏธ๋ฆฌ ๋ณผ ํ•„์š”๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ์ผ๋ฐ˜์ ์œผ๋กœ PDF ์ฃผ์†Œ๊ฐ€ ์žˆ๊ณ  ํŽ˜์ด์ง€์—์„œ PDF ํŒŒ์ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ˆ˜๋‹จ์„ ํ†ตํ•ด ๋ฏธ๋ฆฌ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ...

Oct 7, 2025 ยท 7 min. read
ใ‚ทใ‚งใ‚ข

์„œ๋ฌธ

๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ์ข…์ข… PDF๋ฅผ ๋ฏธ๋ฆฌ ๋ณผ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์‹œ๊ฐ„์€ ์ผ๋ฐ˜์ ์œผ๋กœ PDF ์ฃผ์†Œ์ด๋ฉฐ, ์–ด๋–ค ๋ฐฉ๋ฒ•์œผ๋กœ ํŽ˜์ด์ง€์—์„œ PDF ํŒŒ์ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ• ๋˜๋Š” ํƒ€์‚ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ:

  • embed
  • iframe
  • pdf.js
  • react-pdf

๊ทธ๋Ÿฌ๋‚˜ PDF๊ฐ€ ์ƒ๋Œ€์ ์œผ๋กœ ํฐ ๊ฒฝ์šฐ ๋А๋ฆฐ ๋กœ๋”ฉ ์†๋„์™€ ๋„ˆ๋ฌด ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋Š” ๋” ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. PDF ์šฉ๋Ÿ‰์ด ํด์ˆ˜๋ก ๋„คํŠธ์›Œํฌ ์ „์†ก ์‹œ๊ฐ„์ด ๊ธธ์–ด์งˆ ์ˆ˜๋ฐ–์— ์—†์–ด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์ด ๋‚˜๋น ์ง€๊ณ , ํฐ PDF๋ฅผ ์—ด๋ฉด ๋” ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฐจ์ง€ํ•˜์—ฌ ํƒญ/๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฉˆ์ถ”๊ฑฐ๋‚˜ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋ฐฉ๋ฒ•

์šฐ์„ , ๊ธฐ์กด์˜ PDF ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋ฐฉ๋ฒ•์„ ์‚ดํŽด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋Š” ๋‘ ๊ฐ€์ง€ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋ฐฉ๋ฒ•์„ ๊ฐ„๋‹จํžˆ ์–ธ๊ธ‰ํ•˜๊ณ  ๋งค์šฐ ๊ฐ„๋‹จํ•˜๋ฉฐ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

js
import { PDF_URL } from "./constant" const Normal = () => { return ( <div> <embed src={PDF_URL} type="application/pdf" width="100%" height="600px"></embed> <iframe width={'100%'} height={600} src={PDF_URL} /> </div> ) } export default Normal

ํ•˜๋‚˜๋Š” ๋ฏธ๋ฆฌ ๋ณด๊ธฐ์— ์ž„๋ฒ ๋“œ ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ์ž์ฒด PDF ๋ Œ๋”๋ง ์—”์ง„์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ์— iframe ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์ผ๋ฐ˜์ ์œผ๋กœ ๋” ๋งŽ์€ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ €์—๊ฒŒ๋Š” 100ํŽ˜์ด์ง€ + PDF๊ฐ€ 15M ์ •๋„์ด๊ณ , ๋Œ€์—ญํญ์ด 4M์ธ ์„œ๋ฒ„์—์„œ๋Š” ์ „์†ก์— 30์ดˆ ์ •๋„ ๊ฑธ๋ฆฌ๋Š”๋ฐ, ์—ฌ์ „ํžˆ ๊ฝค ๊ธด ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ์€ PDF ํŽ˜์ด์ง• ๋กœ๋”ฉ ๋ฐ ๋ Œ๋”๋ง์— ๋Œ€ํ•ด ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์šฉ๋Ÿ‰ PDF ๋„คํŠธ์›Œํฌ ์ „์†ก์ด ๋„ˆ๋ฌด ๋А๋ฆฌ๊ณ  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋„ˆ๋ฌด ๋งŽ์ด ์ฐจ์ง€ํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆผ์œผ๋กœ ๋‚˜๋ˆ„๊ธฐ

์ „์ฒด PDF ํŒŒ์ผ์„ ํ•œ ๋ฒˆ ๋กœ๋“œํ•˜๋Š” ๊ฒƒ์ด ๋„ˆ๋ฌด ๋А๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ๋ฏธ๋ฆฌ ๋ณด๊ธฐ๋ฅผ ์œ„ํ•ด ๋” ์ž์„ธํ•œ ๋‹จ์œ„๋กœ ๋ถ„ํ• ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋Š” ๋จผ์ € ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ๋ณ„๋กœ ์ „์ฒด PDF ํŒŒ์ผ์„ ๊ทธ๋ฆผ์œผ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์œผ๋ฉฐ, 1ํŽ˜์ด์ง€ PDF๋Š” 1์žฅ์˜ ๊ทธ๋ฆผ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด๋Ÿฌํ•œ ์‚ฌ์ „ ์ฒ˜๋ฆฌ ํ›„์—๋Š” ์ „์ฒด PDF ํŒŒ์ผ์„ ํ•œ ๋ฒˆ๋งŒ ๋กœ๋“œํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์˜จ๋””๋งจ๋“œ ๋กœ๋“œ ๋˜๋Š” ์Šฌ๋ผ์ด์Šค ๋กœ๋“œ๋ฅผ ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‚ฌ์šฉ์ž์˜ ์ฒซ ํ™”๋ฉด ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ํฌ๊ฒŒ ์ค„์–ด๋“ค์–ด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

PDF

์—ฌ๊ธฐ์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์ „ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋ฉฐ PDF ํŒŒ์ผ์ด ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ pdf-image, ํŠน์ • ์„ค์น˜ ํŠœํ† ๋ฆฌ์–ผ์€ ๋งํฌ๋ฅผ ํด๋ฆญํ•˜์—ฌ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์„ค์น˜ ํ›„ ๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ PDF ํŒŒ์ผ์˜ ๊ฐ ํŽ˜์ด์ง€๋ฅผ ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ „์ฒ˜๋ฆฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

js
const PDFImage = require("pdf-image").PDFImage; const path = require("path"); const fs = require("fs"); const FILE_PATH = path.join(__dirname, "../public/files/test.pdf"); const outputDirectory = path.join(__dirname, "../public/files/tmp"); const pdfImage = new PDFImage(FILE_PATH, { convertOptions: { "-density": 250, // ํ•ด์ƒ๋„๋ฅผ ๋†’์ด๊ณ  ํ•„์š”์— ๋”ฐ๋ผ ์กฐ์ • "-quality": 100, "-trim": null, }, outputDirectory, }); const run = async () => { const info = await pdfImage.getInfo(); for (let i = 0; i < Number(info.Pages); i++) { try { await pdfImage.convertPage(i); } catch (error) { console.log("error", error); } } }; run();

๊ฐ ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ์ด๋ฏธ์ง€๊ฐ€ ์ค€๋น„๋˜๋ฉด ํ•ด๋‹น ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๊ธฐ๋Šฅ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” 100๊ฐœ๊ฐ€ ๋„˜๋Š” ์ด๋ฏธ์ง€๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ๋ Œ๋”๋งํ•  ๋•Œ ํ•œ ๋ฒˆ์— ๋ชจ๋‘ ๋ Œ๋”๋งํ•  ํ•„์š” ์—†์ด ์•ฝ๊ฐ„์˜ ์ง€์—ฐ ๋กœ๋”ฉ์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” IntersectionObserver; ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€์˜ ์ง€์—ฐ ๋กœ๋”ฉ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ๋จผ์ € ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ง€์—ฐ ๋กœ๋”ฉ ํ›…์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค:

  • ์—ฌ๊ธฐ์—์„œ ๊ฐ ์š”์†Œ์— ๊ธฐ๋ณธ ๋†’์ด๋ฅผ ์ง€์ •ํ•œ ๋‹ค์Œ IntersectionObserver; ์‚ฌ์šฉํ•˜์—ฌ ์š”์†Œ๊ฐ€ ๋ทฐํฌํŠธ์— ํ‘œ์‹œ๋˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ทฐํฌํŠธ ๋ฐ˜ํ™˜์— ํ‘œ์‹œ๋˜๋Š” ๊ฒฝ์šฐ ์ด ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.
js
import { useEffect,useRef,useCallback } from "react"; const useObserve = ({ rootRef, itemSelector }) => { const observer = useRef(null); const handlerObserve = entries => { entries.forEach(({ isIntersecting, target }) => { if (isIntersecting) { const targetImg = target.children[0]; targetImg.src = targetImg.dataset.src; // src ์†์„ฑ์„ ์ˆ˜์ •ํ•œ ํ›„ ๋ฐ์ดํ„ฐ-src ์†์„ฑ์„ ์ œ๊ฑฐํ•˜๊ณ  ๋ชจ๋‹ˆํ„ฐ๋ง์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! targetImg.removeAttribute("data-src"); observer.current.unobserve(target); } }); }; const addObserve = () => { const list = document.querySelectorAll(itemSelector); list.forEach(item => { observer.current.observe(item); }); }; const initObserver = useCallback(() => { observer.current = new IntersectionObserver(handlerObserve, { root: rootRef.current, rootMargin: "0px 0px 200px 0px", // ๋ชจ๋‹ˆํ„ฐ ์˜์—ญ ์•„๋ž˜์ชฝ์œผ๋กœ ํ™•์žฅ 200px }); addObserve(); }, []); useEffect(() => { initObserver(); return () => { observer.current.disconnect(); }; }, []); }; export default useObserve;

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค:

js
import { Carousel } from "antd"; import styles from "./index.module.less"; import { LeftOutlined, RightOutlined } from "@ant-design/icons"; import { useState, useEffect, useRef, useMemo, useCallback } from "react"; import { API_PREFIX } from "../../../../env"; import useObserve from "./useObserve"; const defaultImage = ""; const Preview = () => { const [list, setList] = useState(() => { return new Array(105).fill(0).map((item, index) => { return { page: index, originSrc: `${API_PREFIX}/files/tmp/test-${index}.png`, }; }); }); const contentRef = useRef(null); useObserve({ rootRef: contentRef, itemSelector: ".image-item-observe", }); return ( <div className={styles.preview}> <div ref={contentRef} className={styles.content}> {list.map((item, index) => { return ( <div class={`${styles["image-item-wrapper"]} image-item-observe`}> {/* ๋กœ๋”ฉ ๊ณผ์ •์—์„œ ํฐ์ƒ‰ ํ™”๋ฉด ํ˜„์ƒ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ๋ณธ ๊ธฐ๋ณธ ๋งต์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.*/} <img class={styles["image-item"]} src={defaultImage} data-src={item.originSrc} key={index} width="100%" /> </div> ); })} </div> </div> ); }; export default Preview;

์ด๋ฅผ ํ†ตํ•ด PDF ๋ฏธ๋ฆฌ ๋ณด๊ธฐ ๊ธฐ๋Šฅ์„ ์˜จ๋””๋งจ๋“œ ๋ฐฉ์‹์œผ๋กœ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŽ˜์ด์ง€๋ณ„๋กœ ๋‚˜๋ˆ„๊ธฐ

์œ„๋Š” ์—ฌ๋Ÿฌ ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋“œํ•˜์—ฌ PDF์˜ ์ง€์—ฐ ๋กœ๋”ฉ์„ ์ˆ˜ํ–‰ํ•œ ํ›„ PDF๋ฅผ ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ฐฉ๋ฒ•์€ ํฐ PDF๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž‘์€ PDF๋กœ ์ž๋ฅธ ๋‹ค์Œ ์ผ๋ฐ˜ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฏธ๋ฆฌ ๋ณด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋จผ์ € ๋ฐ์ดํ„ฐ๋ฅผ ์ „์ฒ˜๋ฆฌํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  PDF ํŒŒ์ผ์„ ์ž๋ฆ…๋‹ˆ๋‹ค.

js
const fs = require("fs"); const { PDFDocument } = require("pdf-lib"); const path = require("path"); async function splitPDF(inputPath, outputPrefix) { const pdfBytes = await fs.promises.readFile(inputPath); const pdfDoc = await PDFDocument.load(pdfBytes); const totalPages = pdfDoc.getPageCount(); const pagesPerChunk = 10; for (let startPage = 1; startPage <= totalPages; startPage += pagesPerChunk) { const endPage = Math.min(startPage + pagesPerChunk - 1, totalPages); const newPdfDoc = await PDFDocument.create(); for (let pageNum = startPage; pageNum <= endPage; pageNum++) { const [copiedPage] = await newPdfDoc.copyPages(pdfDoc, [pageNum - 1]); newPdfDoc.addPage(copiedPage); } const outputPath = `${outputPrefix}/${Math.floor(endPage / 10)}.pdf`; const newPdfBytes = await newPdfDoc.save(); await fs.promises.writeFile(outputPath, newPdfBytes); console.log(`PDF successfully split from page ${startPage} to ${endPage}.`); } } const FILE_PATH = path.join(__dirname, "../public/files/test.pdf"); const outputDirectory = path.join(__dirname, "../public/files/tmp-file"); splitPDF(FILE_PATH, outputDirectory);

์Šฌ๋ผ์ด์‹ฑ ํ›„ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. iframe์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง์ ‘ ํ•˜๋‚˜์”ฉ ๋ฏธ๋ฆฌ๋ณด๊ณ  ํด๋ฆญํ•˜์—ฌ ๋” ๋งŽ์ด๋กœ๋“œ ํ•œ ๋‹ค์Œ ๋‹ค์Œ ์„ธ๊ทธ๋จผํŠธ๋ฅผ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์œผ๋ฉฐ ๋ถ„ํ•  ๋œ PDF ํŒŒ์ผ์„ ํ•˜๋‚˜์”ฉ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค:

js
import React, { useState, useEffect, useRef } from "react"; import { API_PREFIX } from "../../../../env"; const pdfs = new Array(11) .fill(0) .map((_, index) => `${API_PREFIX}/files/tmp-file/${index + 1}.pdf`); const Split = () => { const [list, setList] = useState([pdfs[0]]); return ( <div> {list.map((url, index) => { return ( <div> <iframe id={`iframe-${index}`} key={index} width={"100%"} height={600} src={url} /> </div> ); })} <button disabled={list.length === pdfs.length} onClick={() => { const arr = [...list]; arr.push(pdfs[arr.length]); setList(arr) }} > ๋” ๋ณด๊ธฐ </button> </div> ); }; export default Split;

๋งˆ์ง€๋ง‰์œผ๋กœ

์œ„์˜ ๋‚ด์šฉ์€ ๋‘ ๊ฐœ์˜ ํฐ PDF ํŒŒ์ผ์„ ๋” ๋น ๋ฅด๊ฒŒ ๋ฏธ๋ฆฌ ๋ณด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ํฅ๋ฏธ๋กœ์šด ๋ฐฉ๋ฒ•์ด ์žˆ์œผ๋ฉด ๋ธŒ๋ ˆ์ธ ์Šคํ† ๋ฐ ํ† ๋ก ๊ณผ ํ•จ๊ป˜ ์˜๊ฒฌ ์„น์…˜์— ์˜ค์‹  ๊ฒƒ์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. ์ฝ์–ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค, ์›ํ•œ๋‹ค๋ฉด ์šฐ๋ ค๋˜๋Š” ์ ์„ ์ง€์ ํ•˜๊ณ  ์นญ์ฐฌํ•ด ์ฃผ์„ธ์š”~!

Read next

๋ฌด๋ฃŒ GPT

ChatGPT๋Š” ์‚ฌ์ „ ํ•™์Šต๋œ ์–ธ์–ด ๋ชจ๋ธ์ธ GPT ์ œํ’ˆ๊ตฐ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์ฑ—๋ด‡์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์งˆ๋ฌธ์— ๋‹ตํ•˜๊ณ , ์žก๋‹ด์„ ํ•˜๊ฑฐ๋‚˜, ๋ฒˆ์—ญ, ๋…ํ•ด ๋“ฑ ํŠน์ • ์ž‘์—…์„ ์™„๋ฃŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ChatGPT๋Š” ๊ณ ๊ฐ ์„œ๋น„์Šค, ์Šค๋งˆํŠธ ํ™ˆ, ์—”ํ„ฐํ…Œ์ธ๋จผํŠธ ๋“ฑ ๋‹ค์–‘ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

Oct 7, 2025 ยท 2 min read