네컷포토부스 제작기(학교 축제)-서버파트
고등학교 축제에서 네컷사진 부스를 운영하고 싶다면? 사진 동아리의 실제 프로젝트 사례를 통해, 네컷사진 촬영 소프트웨어부터 웹 서버 구축 및 공유 시스템 개발까지의 과정을 소개합니다. 학교 로고 커스텀 프레임과 QR 코드 생성 등 유용한 기능들을 확인해보세요!
우리 고등학교는 매년 교내 축제를 진행한다. 필자는 현재 사진 동아리에 가입되어 있다. 따라서 축제 때 어떤 의미 있는 부스를 운영할지 고민하던 중, 시중의 인생네컷이나 포토이즘과 같은 네컷사진 부스를 운영하면 재미있겠다는 생각이 들었다. 이러한 부스는 단순히 사진을 찍는 행위를 넘어 사람들에게 추억을 기록하고 공유하는 재미를 선사할 수 있다는 점에서 매력적이었다. 또한 학교 로고나, 마스코트를 사용하여 커스텀 프레임을 사용한다면, 학교 축제라는 의미가 포함될 수 있기 때문에 좋다고 생각했다.
그래서 네컷사진 부스를 제작하기로 결심했다. 이 프로젝트는 혼자 진행하기에는 벅찼기 때문에, 같은 동아리 친구 한 명과 함께 개발을 진행했다. 우리는 개발 과정을 두 부분으로 나누었다:
- 네컷사진 촬영 및 저장 소프트웨어 개발
- 웹 서버와 공유 시스템 개발
필자는 주로 웹 서버 및 공유 시스템을 담당했으며, 나머지 네컷사진 촬영 및 저장 소프트웨어는 친구가 개발하였다. 다음은 프로젝트의 전반적인 개발 과정을 소개하겠다.
개발 과정
1. 요구사항 정의 및 기능 설계
처음에는 단순히 네컷사진을 촬영하고 다운로드만 제공하려고 했지만, 프로젝트를 구체화하면서 더 많은 기능이 필요하다고 판단했다. 축제 현장에서 사용자가 사진을 찍고 쉽게 공유할 수 있어야 했고, 촬영된 결과물을 효율적으로 관리하기 위한 관리자 시스템도 필요했다. 이를 통해 최종적으로 구현해야 할 기능은 다음과 같이 정의되었다:
- 포토부스에서 찍힌 사진이 저장된 폴더 실시간 감지
- 감지된 폴더에 들어있는 사진을 보여주는 웹사이트 구현
- 다운로드 기능
- 폴더명을 해시 처리하여 보안 강화
- 생성된 링크를 QR 코드로 변환
- 관리자 페이지에서 모든 사진 저장 상황 판별
- 부스 외부에서 촬영된 사진을 전시할 빔 프로젝터용 페이지
이 요구사항을 기반으로 시스템 설계에 들어갔다.
2. 기술 선택 및 환경 설정
- 프로그래밍 언어 및 프레임워크:
- 웹 서버는 **Node.js(Express)**를 사용하여 구현하였다.
- 사진 촬영과 저장은 친구가 Flask를 사용하여 개발했다.
- 추가 라이브러리:
- Chokidar: 사진이 저장되는 폴더를 실시간으로 감지
- QRCode: 각 링크를 QR 코드로 변환
- Moment.js: 날짜와 시간을 쉽게 관리
- Crypto: 해시 생성
사진은 photos/
폴더에 저장되며, 각 폴더 이름은 날짜와 시간(예: 202412220855
)으로 자동 생성된다. 네컷사진 부스와 연결은 vpn터널을 만들어서 네트워크 드라이브를 생성하여 서버와 네컷사진 부스를 이어놓았다. 그리고 서버 구동은 미리 구현해놓은 홈서버에서 nodejs를 실행시켰다.
3. 시스템 구현
1) 폴더 실시간 감지
촬영된 사진은 동적으로 저장되기 때문에, 새로운 폴더 생성 및 사진 저장을 실시간으로 감지해야 했다. 이를 위해 Chokidar를 사용하여 파일 시스템 이벤트를 모니터링하도록 구현했다.
const chokidar = require('chokidar');
const watcher = chokidar.watch('./photos', { persistent: true });
watcher.on('addDir', (dirPath) => {
console.log(`새 폴더 감지: ${dirPath}`);
});
2) 사진 표시 및 다운로드 구현
웹 페이지를 통해 사용자가 촬영된 사진을 볼 수 있도록 했으며, 사진을 다운로드할 수 있는 버튼을 추가했다. 사진은 Node.js의 Express
서버를 통해 정적 파일로 제공하였다.
app.use('/photos', express.static('photos'));
QR코드로 접속하면 아래 화면이 반겨준다.
추가로 실제 포토이즘처럼 영상까지 넣으려 했지만.. 서버 트래픽을 너무 많이 먹을거같아서 ㅋㅋㅋ(사실은 학교 인터넷이 느리다) 추가하지 못했다 ㅠ
3) 폴더명을 해시 처리하여 보안 강화
폴더 이름이 단순히 날짜와 시간으로 구성되어 있다면, 다른 사용자가 URL을 유추해 접근할 가능성이 있다. 이를 방지하기 위해 SHA-256 해시 알고리즘을 사용하여 폴더명을 변환하였다.
const crypto = require('crypto');
function createHash(folderName) {
return crypto.createHash('sha256').update(folderName).digest('hex').slice(0, 10);
}
이런식으로 포토부스에서 사진이 저장될 때 마다 폴더가 인식되고 폴더명을 기반으로 하여 해시값이 생성된다. 그리고 해시값을 링크로 하는 개별 페이지가 자동으로 생성된다.
4) QR 코드 생성
사용자가 손쉽게 사진에 접근할 수 있도록 QR 코드를 생성했다. 이는 QRCode 라이브러리를 사용하여 구현하였다.
const QRCode = require('qrcode');
QRCode.toDataURL('https://example.com/photo/c1676bac6c', (err, url) => {
console.log(url); // QR 코드 이미지 데이터
});
5) 관리자 페이지
촬영된 모든 사진과 QR 코드 링크를 한눈에 확인할 수 있는 관리자 페이지를 구현했다. 관리자 페이지는 비밀번호를 통해 접근할 수 있도록 하여 보안을 강화하였다.
6) 빔 프로젝터 페이지
부스 외부에 설치된 빔 프로젝터로 촬영된 사진을 실시간으로 표시하기 위해 별도의 페이지를 제작하였다. CSS 그리드를 사용하여 촬영된 사진이 일정한 간격으로 배치되도록 하였고, 새로운 사진이 추가되면 자동으로 갱신되도록 설정하였다.
실제 구동 영상도 있었으면 좋았을 텐데.... 축제 때 찍은 사진이 날아간 것 같다 ㅠ
그래서 이건 추후에 채워넣어 보겠다.
프레임은 미리캔버스에서 대부분 만들었다. 위에 있는 한장은 우리가 만들었지만 예술적감각이 부족해서 ㅋㅋ?
나머지 프레임은
여자애들한테 도움을 청했다. (확실히 잘만든다) + 현수형의 도움
하드웨어 부분도 빼먹을 수 없다. 실제 네컷부스와 유사한 경험을 주기 위해, 27인치 터치모니터를 채택하였다. 또한 dslr카메라를 연결하여 사진의 퀄리티를 높였다. 그리고 조명은 ㅋㅋㅋㅋ 생각만해도 어이없긴한데.... 학교 독서실에 있는걸 가져와서 사용했다 ㅋㅋㅋㅋ... 여러개를 난잡하게 설치해놔서 그림자가 약간 보였다. 이부분은 조금 아쉬운듯
아 가장 아쉬운 부분이 있었다. 네컷 사진을 인화하는 프린터가 너무 느렸다. 포토용지에 출력하여 실제 네컷사진만큼 고해상도로 선명하게 출력은 되었지만 한장 출력되는데 1분30초가량 걸렸다. 아마 추후에는 프린터를 바꾸거나 해야될 것 같다.
축제 때 반응을 보니 만들기 잘 했다는 생각이 들었다. 학생들은 물론이고 선생님들, 행정실 직원분들 까지 오셔서 웃으시며 찍고 사진을 인화해서 가는 모습을 보니 무척이나 뿌듯했다. (축제 끝나고 몸살걸렸다 사실은 너무 힘들었다 ㅋㅋㅋㅋ)