CSS&JS/⚡Thinkers

[JS]첨부파일 이미지 canvas에서 픽셀 모자이크화 시키기

arancia_ 2026. 3. 6. 10:31

See the Pen input file to mosaic pixel canvas by Oh Ikmyeong (@dpffpself) on CodePen.

HTML

1
2
3
4
5
6
7
8
9
10
11
    <label>
        <span>원하는 이미지를 첨부하세요</span>
        <input type="file" id="ipt-file" accept="image/*" />
    </label>
    <label>
        <span>픽셀 사이즈 조정</span>
        <input type="number" id="ipt-size" value="10" min="1" />
    </label>
    <div class="cv-wrap">
        <canvas id="cv"></canvas>
    </div>
cs

CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
 
        body {
            display: flex;
            flex-flow: column nowrap;
            justify-content: center;
            align-items: center;
            gap: 10px;
            min-height: 100vh;
            padding: 40px 0;
            background: #ccc;
        }
 
        .cv-wrap {
            position: relative;
            width: 80%;
            max-width: 600px;
            background: #fff;
        }
 
        #cv {
            width: 100%;
            height: 100%;
        }
cs

JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
const $file = document.getElementById("ipt-file");
const $cv = document.getElementById("cv");
const $size = document.getElementById("ipt-size");
const ctx = $cv.getContext("2d");
let lastChangeEvent = null;
 
/* 첨부파일 받기 시작할때 */
$file.addEventListener("change", on_file_change);
 
/* 픽셀 사이즈 조정할때 */
$size.addEventListener("change", () => {
    if (!lastChangeEvent) { return console.warn("파일 정보 없음"); }
    on_file_change(lastChangeEvent);
});
 
/**
    * 첨부파일 전달 받았을때
    * @memo file > base64 > Image > canvas
    * */
function on_file_change(e) {
    const file = e.target.files[0];
    if (!file) {
        lastChangeEvent = null;
        return console.warn("no file");
    }
    lastChangeEvent = e;
    const reader = new FileReader();
    reader.readAsDataURL(file);
 
    reader.onload = (evt) => {
        const $img = new Image();
        $img.src = evt.target.result;
        $img.onload = () => {
            $cv.width = $img.width;
            $cv.height = $img.height;
            draw_pixelated($img, Math.max(1, $size.valueAsNumber));
        }//onload:img
    }//onload:reader
}//on_file_change
 
/**
    * 캔버스에 그리기 시작
    * */
function draw_pixelated($img, pixelSize) {
    const w = $cv.width;
    const h = $cv.height;
    const smallW = Math.ceil(w / pixelSize);
    const smallH = Math.ceil(h / pixelSize);
 
    //픽셀 느낌 나게
    ctx.imageSmoothingEnabled = false;
 
    //작은 해상도로 그리고
    ctx.drawImage($img, 00, smallW, smallH);
 
    //다시 확대
    ctx.drawImage($cv, 00, smallW, smallH, 00, w, h);
}//draw_pixelated
 
cs