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

Rust로 작성한 WebAssembly 확장형 모듈을 Web application에서 사용하기.

by rachel414 님의 블로그 2025. 8. 2.
반응형

Rust + WebAssembly 실전 프로젝트: 웹 기반 이미지 필터링 앱

본 문서는 Rust로 작성된 모듈을 WebAssembly(WASM)로 컴파일하고, 이를 웹 애플리케이션에서 활용하는 실제 예제 프로젝트를 소개합니다. Rust는 메모리 안전성, 성능, 안정성을 갖춘 시스템 프로그래밍 언어로, WASM과 결합할 경우 웹 애플리케이션에서 고성능 로직을 효율적으로 실행할 수 있습니다. 이 프로젝트는 이미지 필터링 기능을 Rust로 구현하고, 이를 웹에서 실시간으로 사용할 수 있도록 WASM으로 컴파일하여 JavaScript와 연동합니다.

Rust + WebAssembly 실전 프로젝트: 웹 기반 이미지 필터링 앱

프로젝트 개요

  • 기능: 이미지 그레이스케일 필터 적용
  • 언어: Rust (백엔드 필터 로직)
  • 플랫폼: WebAssembly (wasm32-unknown-unknown)
  • 프론트엔드: HTML5, JavaScript (Canvas API)
  • 도구: wasm-pack, cargo, webpack

기술 아키텍처

Rust 코드는 이미지 데이터의 픽셀 배열을 받아 각 픽셀을 변환하는 필터를 수행합니다. 변환된 데이터는 다시 JavaScript로 반환되어 웹 브라우저의 Canvas API를 통해 화면에 그려집니다. Rust에서 제공하는 wasm-bindgen 매크로를 사용하여 JavaScript와 상호작용하며 WASM 모듈은 브라우저 내에서 직접 실행됩니다.

Rust 코드 예제 (lib.rs )

use wasm_bindgen::prelude::*;

// 웹에서 호출 가능한 함수로 지정
#[wasm_bindgen]
pub fn grayscale(data: &mut [u8]) {
    for chunk in data.chunks_exact_mut(4) {
        let r = chunk[0] as u32;
        let g = chunk[1] as u32;
        let b = chunk[2] as u32;
        let avg = ((r + g + b) / 3) as u8;
        chunk[0] = avg;
        chunk[1] = avg;
        chunk[2] = avg;
        // chunk[3]는 alpha (불변)
    }
}
  

위 함수는 4바이트(RGBA) 단위로 배열을 순회하면서 각 픽셀을 평균값으로 변환하여 흑백 효과를 줍니다. Rust의 성능 덕분에 수천 개 이상의 픽셀도 빠르게 처리됩니다.

wasm-pack을 이용한 빌드 과정

  1. Rust 라이브러리 프로젝트 생성: cargo new --lib image_filter
  2. Cargo.toml 수정:
    
    [dependencies]
    wasm-bindgen = "0.2"
          
  3. 타겟 플랫폼 추가: rustup target add wasm32-unknown-unknown
  4. 빌드 실행: wasm-pack build --target web

빌드 결과는 pkg/ 디렉토리에 생성되며, 여기에는 WebAssembly 모듈 (.wasm 파일)과 JavaScript 바인딩 코드가 포함됩니다.

JavaScript 통합 (index.js)

import init, { grayscale } from "./pkg/image_filter.js";

async function applyFilter() {
  await init(); // WASM 모듈 초기화

  const canvas = document.getElementById("canvas");
  const ctx = canvas.getContext("2d");
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  
  grayscale(imageData.data); // Rust 함수 호출

  ctx.putImageData(imageData, 0, 0); // 변형된 이미지 출력
}
  

HTML 구조 (index.html)

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>WASM 이미지 필터링</title>
</head>
<body>
  <h1>이미지 필터 적용</h1>
  <input type="file" id="upload" />
  <br/>
  <canvas id="canvas" width="500" height="500"></canvas>
  <br/>
  <button onclick="applyFilter()">그레이스케일 필터 적용</button>
  <script type="module" src="index.js"></script>
</body>
</html>
  

응용 가능성 및 실제 활용 분야

위와 같은 방식으로 Rust + WASM을 활용하면, 다양한 분야에서 웹 기반 고성능 처리가 가능해집니다. 예를 들어,

  • 이미지 편집기 (포토샵 클론)
  • 오디오 필터 처리 (리버브, 노이즈 제거 등)
  • 비디오 프레임 필터링 및 실시간 효과
  • 수학/통계 계산기 (복잡한 수식, 행렬 연산 등)
  • 생명과학/의료 데이터 시각화 및 분석 도구

Rust + WASM을 사용하는 이유

Rust는 C/C++에 비견되는 성능을 자랑하면서도 메모리 안정성을 보장합니다. 특히 WebAssembly로 컴파일할 경우, 성능 저하 없이 웹에서도 네이티브급 연산이 가능합니다. JavaScript 단독으로 구현하면 느리거나 비효율적인 연산을 Rust로 처리하면 브라우저의 리소스를 훨씬 효율적으로 사용할 수 있습니다.

결론

이 프로젝트는 Rust와 WebAssembly의 결합이 어떻게 웹 애플리케이션의 성능과 효율성을 극대화할 수 있는지를 보여주는 실제적인 예입니다. WASM은 더 이상 실험적인 기술이 아니라, 고성능 웹 앱의 핵심 구성 요소로 자리잡고 있습니다. Rust 생태계의 안정성과 도구 지원 덕분에, 복잡한 연산이 필요한 웹 프로젝트에서도 Rust + WASM을 활용한 아키텍처는 점점 보편화되고 있습니다.

반응형