본문 바로가기
카테고리 없음

3탄: 드래그 앤 드롭 + 이미지 변환 기능 추가 (최종 정리)

by 세상을읽는눈 2025. 3. 21.
반응형

🚀 목표:

  • 드래그 앤 드롭으로 이미지를 추가
  • 파일 경로를 안전하게 전달하고 확인
  • 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 덕분에 가능한 일이었습니다! 😊
처음엔 막막했던 프로젝트였지만, 하나씩 해결해 나가면서 많은 걸 배울 수 있었어요.

아직 완벽하진 않지만, 최종 완성되면 코드 공개와 함께 다시 돌아오겠습니다! 🔥
앞으로도 더 좋은 기능을 추가해서, 블로그 활동에 꼭 필요한 설치형 이미지 변환기 & 캡처 도구로 발전시켜 나가려고 합니다.

여러분도 함께 도전해 보세요! 🚀

반응형