🚀 목표:
- 드래그 앤 드롭으로 이미지를 추가
- 파일 경로를 안전하게 전달하고 확인
- Sharp 라이브러리를 이용해 이미지 변환
1️⃣ 앱 기본 구조 (최종 파일 트리)
📂 프로젝트 폴더 (image-converter/)
image-converter/
├── node_modules/
├── index.html
├── main.js
├── bridge.js
├── package.json
⚠️ bridge.js 파일이 꼭 있어야 하고, main.js에서 불러와야 합니다!
2️⃣ main.js (Electron 메인 프로세스)
📄 VS Code에서 main.js를 열고 아래 코드로 수정하세요.
const { app, BrowserWindow, ipcMain } = require("electron");
const path = require("path");
const fs = require("fs");
const sharp = require("sharp");
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, "bridge.js"), // ✅ 정확한 경로 설정
contextIsolation: true, // ✅ 보안 설정 필수
enableRemoteModule: false,
nodeIntegration: false,
},
});
win.loadFile("index.html");
}
app.whenReady().then(createWindow);
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
// ✅ 이미지 변환 기능 추가
ipcMain.on("process-file", (event, filePath) => {
if (!filePath || !fs.existsSync(filePath)) {
event.reply("conversion-failed", "파일을 찾을 수 없습니다.");
return;
}
const outputFilePath = filePath.replace(/\.(jpg|png)$/, ".webp"); // WebP로 변환
sharp(filePath)
.toFormat("webp")
.toFile(outputFilePath)
.then(() => {
event.reply("conversion-success", outputFilePath);
})
.catch((err) => {
console.error("이미지 변환 오류:", err);
event.reply("conversion-failed", "변환 실패");
});
});
✅ 변경 내용:
- preload: path.join(__dirname, "bridge.js") → bridge.js를 정확하게 로드하도록 설정
- ipcMain.on("process-file", (event, filePath) => { ... }) → Sharp 라이브러리로 이미지 변환 기능 추가
- .toFormat("webp") → JPG, PNG를 WebP로 변환
3️⃣ bridge.js (Renderer와 Main 연결)
📄 VS Code에서 bridge.js를 열고 아래 코드로 수정하세요.
const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld("electron", {
selectFile: (callback) => {
ipcRenderer.on("selected-file", (event, filePath) => {
console.log("📂 파일 경로:", filePath);
if (filePath && filePath !== "undefined") {
callback(filePath);
} else {
console.error("❌ 파일 경로를 가져올 수 없습니다.");
}
});
},
sendFilePath: (filePath) => {
ipcRenderer.send("process-file", filePath);
},
onConversionSuccess: (callback) => {
ipcRenderer.on("conversion-success", (event, outputPath) => {
callback(outputPath);
});
},
onConversionFailed: (callback) => {
ipcRenderer.on("conversion-failed", (event, message) => {
callback(message);
});
},
});
✅ 변경 내용:
- window.electron 객체에 파일 변환 기능 추가
- onConversionSuccess() & onConversionFailed() → 변환 결과를 Renderer로 전달
4️⃣ index.html (프론트엔드 UI + 이벤트 처리)
📄 VS Code에서 index.html을 열고 아래 코드로 수정하세요.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>설치형 이미지 변환기</title>
<style>
body { text-align: center; font-family: Arial, sans-serif; }
h1 { font-size: 24px; }
#drop-zone {
width: 80%;
height: 200px;
margin: 20px auto;
border: 2px dashed #007bff;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
color: #007bff;
}
</style>
</head>
<body>
<h1>설치형 이미지 변환기</h1>
<p>이미지를 드래그하거나 클릭해서 업로드하세요.</p>
<div id="drop-zone">이미지 파일을 여기에 드롭하세요.</div>
<p id="output"></p>
<script>
const dropZone = document.getElementById("drop-zone");
const output = document.getElementById("output");
dropZone.addEventListener("dragover", (event) => {
event.preventDefault();
dropZone.style.borderColor = "green";
});
dropZone.addEventListener("dragleave", () => {
dropZone.style.borderColor = "#007bff";
});
dropZone.addEventListener("drop", (event) => {
event.preventDefault();
dropZone.style.borderColor = "#007bff";
const file = event.dataTransfer.files[0];
if (file) {
console.log("📂 선택된 파일:", file.path);
output.textContent = `선택된 파일: ${file.path}`;
window.electron.sendFilePath(file.path);
}
});
window.electron.onConversionSuccess((outputPath) => {
output.innerHTML = `✅ 변환 완료! <a href="file://${outputPath}" download>변환된 파일 다운로드</a>`;
});
window.electron.onConversionFailed((message) => {
output.textContent = `❌ 변환 실패: ${message}`;
});
</script>
</body>
</html>
✅ 변경 내용:
- dropZone.addEventListener("drop", (event) => {...}) → 파일 드래그 앤 드롭 처리
- window.electron.sendFilePath(file.path); → 파일 경로를 Main 프로세스로 전달
- window.electron.onConversionSuccess() → 변환 완료 후 다운로드 링크 제공
- window.electron.onConversionFailed() → 변환 실패 시 메시지 출력
🚀 5️⃣ 실행 방법 (최종 테스트)
1️⃣ 파일 저장 (Ctrl + S)
수정한 모든 파일을 저장하세요.
- main.js
- bridge.js
- index.html
2️⃣ 앱 실행 (npm start)
📂 VS Code **터미널(PowerShell)**에서 아래 명령어 실행
npm start
3️⃣ 테스트 시나리오
✅ 이미지 드래그 앤 드롭 테스트
✅ 변환된 파일 다운로드 확인
✅ 개발자 도구(Ctrl + Shift + I)에서 오류가 없는지 확인
🛠️ 6️⃣ 최종 체크리스트
✅ bridge.js가 main.js와 같은 폴더에 있는가?
✅ main.js에서 contextIsolation: true로 설정했는가?
✅ 파일 드래그 시 개발자 도구(Console)에서 📂 선택된 파일: 경로가 출력되는가?
✅ WebP 변환 후 파일 다운로드 링크가 표시되는가?
그러고도 계속 테스트를 거치면서 지피티와 대화하고 프로그램을 발전시켜나가야할꺼같습니다.
여전히 테스트 중이지만, 여기까지도 GPT 덕분에 가능한 일이었습니다! 😊
처음엔 막막했던 프로젝트였지만, 하나씩 해결해 나가면서 많은 걸 배울 수 있었어요.
아직 완벽하진 않지만, 최종 완성되면 코드 공개와 함께 다시 돌아오겠습니다! 🔥
앞으로도 더 좋은 기능을 추가해서, 블로그 활동에 꼭 필요한 설치형 이미지 변환기 & 캡처 도구로 발전시켜 나가려고 합니다.
여러분도 함께 도전해 보세요! 🚀