이번 포스트에서는 p5.js를 사용하여 모자이크 효과를 만드는 방법에 대해 알아보겠습니다. 모자이크 효과는 이미지를 작은 타일로 분할하여 독특한 시각적 효과를 만들어내는 기술입니다. p5.js의 강력한 이미지 처리 기능을 활용하여 쉽게 모자이크 효과를 구현할 수 있습니다.
p5.js로 구현하는 모자이크 효과 만들기
p5.js로 구현하는 모자이크 효과 만들기
위의 목차를 클릭하면 해당 글로 자동 이동 합니다.
이미지 로드 및 표시
p5.js에서 이미지를 로드하기 위해선 서버를 사용해야합니다. 인터넷 url주소를 사용하셔도 되지만 자신이 가지고 있는 사진을 이용하기 위해선 서버를 열어 놓아야 합니다. 그래서 간단히 파이썬 플라스크를 이용해서 만들어보겠습니다.
from flask import Flask, send_from_directory
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # 모든 경로에 대해 CORS 활성화
# 정적 파일을 제공하는 라우트
@app.route('/assets/<path:filename>')
def serve_assets(filename):
return send_from_directory('assets', filename)
if __name__ == '__main__':
app.run(debug=True)
모자이크 효과 구현
따로 코드를 나누지 않고 html에서 다 사용하는 방향으로 하겠습니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/p5@1.9.3/lib/p5.js"></script>
<title> p5js Image</title>
</head>
<body>
<script>
let img; // 변수 'img' 선언
let mosaicSize = 20;
let imgOrigin;
function preload(){
//img = loadImage('http://127.0.0.1:5000/assets/hen.jpg'); // 서버에서 이미지 불러올때
img = loadImage('https://media.istockphoto.com/id/1496414074/ko/%EC%82%AC%EC%A7%84/%EC%95%84%EC%B9%A8%EC%97%90-%EC%9D%BC%EC%B6%9C-%ED%95%98%EB%8A%98%EA%B3%BC-%ED%95%A8%EA%BB%98-kawah-ijen-%ED%99%94%EC%82%B0%EC%9D%98-%EB%B6%84%ED%99%94%EA%B5%AC%EC%97%90-%EC%84%9C-%EC%9E%88%EB%8A%94-%EC%97%AC%ED%96%89%EC%9E%90-%EB%82%A8%EC%9E%90.jpg?s=1024x1024&w=is&k=20&c=-1AKj3iKKKdpCYyrovJGAxbhfKTtTzWDzqoNfQ_c1mI='); // 이미지 불러오기
imgOrigin = img;
}
function setup() {
createCanvas(2000, 2000);
image(img, 0, 0 , img.width / 2, img.height / 2);
loadPixels();
// 각 영역의 평균 색상값을 계산하여 모자이크 효과 적용
for (let y = 0; y < height; y += mosaicSize) {
for (let x = 0; x < width; x += mosaicSize) {
let sumR = 0, sumG = 0, sumB = 0;
let count = 0;
// 해당 영역의 픽셀들의 색상값을 합산
for (let j = 0; j < mosaicSize; j++) {
for (let i = 0; i < mosaicSize; i++) {
let px = x + i;
let py = y + j;
// 캔버스 영역을 벗어나지 않도록 확인
if (px < width && py < height) {
let index = (px + py * width) * 4;
sumR += pixels[index];
sumG += pixels[index + 1];
sumB += pixels[index + 2];
count++;
}
}
}
// 평균 색상값 계산
let avgR = sumR / count;
let avgG = sumG / count;
let avgB = sumB / count;
// 해당 영역의 모든 픽셀을 평균 색상값으로 설정
for (let j = 0; j < mosaicSize; j++) {
for (let i = 0; i < mosaicSize; i++) {
let px = x + i;
let py = y + j;
// 캔버스 영역을 벗어나지 않도록 확인
if (px < width && py < height) {
let index = (px + py * width) * 4;
pixels[index] = avgR;
pixels[index + 1] = avgG;
pixels[index + 2] = avgB;
}
}
}
}
}
updatePixels(); // 변경된 픽셀을 적용
}
function draw(){
image(imgOrigin, img.width / 2, 0 , imgOrigin.width / 2, imgOrigin.height / 2);
}
</script>
</body>
</html>
각각 나눠서 설명을 드리도록 하겠습니다.
아래 코드는 이미지를 mosaicSize로 지정된 크기의 작은 영역으로 나누기 위한 중첩 반복문입니다. sumR, sumG, sumB는 각 영역 내 픽셀들의 RGB 색상값을 합산하기 위한 변수이며, count는 해당 영역 내 픽셀 수를 세기 위한 변수입니다.
for (let y = 0; y < height; y += mosaicSize) {
for (let x = 0; x < width; x += mosaicSize) {
let sumR = 0, sumG = 0, sumB = 0;
let count = 0;
현재 영역 내의 각 픽셀에 대해 RGB 색상값을 합산하는 중첩 반복문입니다. px와 py는 현재 픽셀의 x, y 좌표를 나타내며, index는 pixels 배열에서 해당 픽셀의 색상값이 저장된 인덱스를 계산합니다. 그런 다음 sumR, sumG, sumB에 각각의 색상값을 더하고, count를 증가시킵니다. 이때 캔버스 영역을 벗어나는 픽셀은 건너뜁니다.
for (let j = 0; j < mosaicSize; j++) {
for (let i = 0; i < mosaicSize; i++) {
let px = x + i;
let py = y + j;
// 캔버스 영역을 벗어나지 않도록 확인
if (px < width && py < height) {
let index = (px + py * width) * 4;
sumR += pixels[index];
sumG += pixels[index + 1];
sumB += pixels[index + 2];
count++;
}
}
}
이 부분에서는 현재 영역 내 픽셀들의 평균 RGB 색상값을 계산합니다. 각 색상값의 합을 픽셀 수로 나누어 평균값을 구합니다.
let avgR = sumR / count;
let avgG = sumG / count;
let avgB = sumB / count;
여기는 현재 영역 내의 모든 픽셀에 대해 앞서 계산한 평균 RGB 색상값을 할당합니다. 이렇게 하면 해당 영역 내의 모든 픽셀이 동일한 색상값을 가지게 되어 모자이크 효과가 생깁니다. 이때도 캔버스 영역을 벗어나는 픽셀은 건너뜁니다.
for (let j = 0; j < mosaicSize; j++) {
for (let i = 0; i < mosaicSize; i++) {
let px = x + i;
let py = y + j;
// 캔버스 영역을 벗어나지 않도록 확인
if (px < width && py < height) {
let index = (px + py * width) * 4;
pixels[index] = avgR;
pixels[index + 1] = avgG;
pixels[index + 2] = avgB;
}
}
}
}
}
이 코드는 실제로 되는 코드가 안올라가네요... 아마 이미지를 불러오는 부분이 있어서 막히는게 있는것 같습니다. ㅠ
이렇게 p5js를 사용해서 모자이크 효과를 만들어보았습니다. 이 과정은 OpenCV와도 비슷합니다. OpenCV를 하셨던 분들이라면 좀 더 쉽게 하실 수 있을 겁니다. 다음에 해볼 내용이나 해줬으면 하는 내용이 있다면 알려주세요!
추천글
디지털 아트의 세계로 첫발을 내딛다: p5.js로 시작하는 창의적 여정
초보자도 쉽게 따라할 수 있는 웹 기반 GLSL 쉐이더 프로그래밍
'튜토리얼 > p5js' 카테고리의 다른 글
p5.js로 마우스 클릭 시 랜덤한 모양 생성하기 (0) | 2024.05.25 |
---|---|
p5.js로 인터랙티브 도형 만들기 - 마우스 위치에 따라 움직이는 도형 (0) | 2024.05.12 |
p5.js로 실시간 사용자 입력 렌더링하기 (0) | 2024.05.09 |
클릭하면 변하는 버튼: p5.js로 색상 변경하기 (0) | 2024.05.08 |
디지털 아트의 세계로 첫발을 내딛다: p5.js로 시작하는 창의적 여정 (0) | 2024.04.27 |