QR Code - boostcamp-2020/Project15-C-Client-Based-Formula-Editor GitHub Wiki

QR ์ฝ”๋“œ(์˜์–ด: QR code, Quick Response code)์€ ํ‘๋ฐฑ ๊ฒฉ์ž๋ฌด๋Šฌ ํŒจํ„ด์œผ๋กœ ์ •๋ณด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋งคํŠธ๋ฆญ์Šค ํ˜•์‹์˜ ์ด์ฐจ์› ์ฝ”๋“œ์ด๋‹ค. ๋น„์Šทํ•œ ์šฉ๋„๋กœ ๋จผ์ € ์‚ฌ์šฉ๋œ ์ด ์ฐจ์› ์ฝ”๋“œ๋กœ๋Š” ๋ฐ”์ฝ”๋“œ๊ฐ€ ์žˆ๋‹ค. ๋ฐ”์ฝ”๋“œ๋Š” ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ๋‹จ์ˆœํ•œ ๋ง‰๋Œ€๊ธฐ ๋ชจ์–‘์˜ ๋ฐ”๋ฅผ ์ด์ฐจ์›์œผ๋กœ ๋‚˜์—ดํ•œ ๊ฒƒ์ด๋‹ค. QR์ฝ”๋“œ๋Š” ์ฃผ๋กœ ํ•œ๊ตญ, ์ผ๋ณธ, ์ค‘๊ตญ, ์˜๊ตญ, ๋ฏธ๊ตญ ๋“ฑ์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋ฉฐ ๋ช…์นญ์€ ๋ด์†Œ ์›จ์ด๋ธŒ์˜ ๋“ฑ๋ก ์ƒํ‘œ 'Quick Response'์—์„œ ์œ ๋ž˜ํ•˜์˜€๋‹ค. ์ข…๋ž˜์— ๋งŽ์ด ์“ฐ์ด๋˜ ๋ฐ”์ฝ”๋“œ์˜ ์šฉ๋Ÿ‰ ์ œํ•œ์„ ๊ทน๋ณตํ•˜๊ณ  ๊ทธ ํ˜•์‹๊ณผ ๋‚ด์šฉ์„ ํ™•์žฅํ•œ 2์ฐจ์›์˜ ํŒจํ„ด์œผ๋กœ ์ข…ํšก์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์„œ ์ˆซ์ž ์™ธ์— ๋ฌธ์ž์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ณดํ†ต ๋””์ง€ํ„ธ์นด๋ฉ”๋ผ๋‚˜ ์ „์šฉ ์Šค์บ๋„ˆ๋กœ ์ฝ์–ด ๋“ค์—ฌ ํ™œ์šฉํ•œ๋‹ค. ๊ตญ๋ฆฝ๊ตญ์–ด์›์—์„œ๋Š” QR ์ฝ”๋“œ๋ฅผ ์ •๋ณด๋ฌด๋Šฌ๋กœ ๋‹ค๋“ฌ์—ˆ๋‹ค.

QR์ฝ”๋“œ๋Š” 1994๋…„ ์ผ๋ณธ ๋„์š”ํƒ€ ์ž๋™์ฐจ ์žํšŒ์‚ฌ์ธ ๋ด์†Œ ์›จ์ด๋ธŒ๊ฐ€ ๋„์š”ํƒ€ ์ž๋™์ฐจ ์ „์šฉ ๋ถ€ํ’ˆ์„ ๊ตฌ๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ์‹œ์ž‘๋๋‹ค. ๊ธฐ์กด ๋ฐ”์ฝ”๋“œ ๋ฐฉ์‹์ด 1์ฐจ์›์ ์ธ ๊ฐ€๋กœ ์„ ๋งŒ์œผ๋กœ๋Š” ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ์ •๋ณด์˜ ์–‘์ด ์ œํ•œ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ผ์ • ๋ฉด์ ์— ์ •๋ณด๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” 2์ฐจ์› ์ฝ”๋“œ๋ฅผ ๊ฐœ๋ฐœํ•œ ๊ฒƒ์ด๋‹ค. ๊ธฐ์กด์˜ ๋ฐ”์ฝ”๋“œ๊ฐ€ 20์ž ๋‚ด์™ธ์˜ ์ˆซ์ž ์ •๋ณด๋งŒ ์ €์žฅํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, QR์ฝ”๋“œ๋Š” ์ˆซ์ž ์ตœ๋Œ€ 7,089์ž, ๋ฌธ์ž ์ตœ๋Œ€ 4,296์ž๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

QR์ฝ”๋“œ๋Š” ์ •์‚ฌ๊ฐํ˜• ์•ˆ ํ‘๋ฐฑ ๊ฒฉ์ž์„  ์œ„๋กœ ๋‹ค์–‘ํ•œ ๋ฌด๋Šฌ๊ฐ€ ์ž…ํ˜€์ง„ ๊ฒƒ์ด๋‹ค. QR์ฝ”๋“œ๋Š” ํฌ๊ฒŒ 3๊ฐ€์ง€ ํŒจํ„ด์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. ์œ„์น˜ ์ฐพ๊ธฐ ํŒจํ„ด๊ณผ ์–ผ๋ผ์ธ๋จผํŠธ ํŒจํ„ด, ์…€ ํŒจํ„ด ์ด๋‹ค. ์œ„์น˜ ์ฐพ๊ธฐ ํŒจํ„ด์€ ๋ชจ๋“  QR์ฝ”๋“œ์˜ ์„ธ ๋ชจ์„œ๋ฆฌ์— ํฌ๊ฒŒ ์ž๋ฆฌ ์žก๊ณ  ์žˆ๋Š” ์‚ฌ๊ฐํ˜•์ด๋‹ค. ํ•ด๋‹น ๊ธฐ๋Šฅ์€ QR์ฝ”๋“œ๋ฅผ ์ธ์‹๊ธฐ๊ฐ€ 360๋„ ์–ด๋Š ๋ฐฉํ–ฅ์—์„œ ๊ฐ์ง€ํ•˜๋”๋ผ๋„ QR์ฝ”๋“œ์˜ ์œ„์น˜๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ํŒŒ์•…, ๋น ๋ฅธ ์ •๋ณด ํƒ์ƒ‰์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“œ๋Š” ์ผ์ข…์˜ ๋‚˜์นจ๋ฐ˜ ๊ธฐ๋Šฅ์„ ํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ์ธ์‹ ๋ฐ ๋ถ„์„ ์†๋„๊ฐ€ ๋นจ๋ผ์ ธ QR์ฝ”๋“œ๋ž€ ์ด๋ฆ„๋„ โ€˜๋น ๋ฅธ ์‘๋‹ตโ€™(Quick Response)์—์„œ ๋‚˜์™”๋‹ค.

์—ฌ๊ธฐ์— ์–ผ๋ผ์ธ๋จผํŠธ ํŒจํ„ด๊ณผ ์…€ ํŒจํ„ด ๋“ฑ์ด ๋”ํ•ด์ ธ QR์ฝ”๋“œ๋ฅผ ์ด๋ฃฌ๋‹ค. ์–ผ๋ผ์ธ๋จผํŠธ ํŒจํ„ด์€ QR์ฝ”๋“œ์— ์–ผ๋ฃฉ์ด ๋ฌป๊ฑฐ๋‚˜ ๋˜๋Š” ์ผ๊ทธ๋Ÿฌ์ง€๊ฑฐ๋‚˜ ํŒŒ์†๋œ ๊ฒฝ์šฐ์—๋„ ์ธ์‹ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. ์…€ ํŒจํ„ด์€ ํ‘๋ฐฑ ์ ๊ณผ ํฐ์ƒ‰ ์—ฌ๋ฐฑ์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ณณ์ด๋‹ค. QR์ฝ”๋“œ์— ๋‹ด๊ธด ๋ฐ์ดํ„ฐ ์ธ์‹์€ ๋น›์˜ ํก์ˆ˜์™€ ๋ฐ˜์‚ฌ๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ์ ์™ธ์„  ์„ผ์„œ๋ฅผ ํ†ตํ•ด ์ด๋ค„์ง„๋‹ค. ์ ์™ธ์„  ์„ผ์„œ๋Š” ์ ์™ธ์„ ์„ ๋ฐฉ์ถœํ•˜๋Š” ๋ฐœ๊ด‘์†Œ์ž์™€ ์ด๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ์ˆ˜๊ด‘์†Œ์ž๋กœ ๋ถ„๋ฆฌ๋ผ ์žˆ๋‹ค. QR์ฝ”๋“œ์˜ ๊ฒ€์€์ƒ‰์€ ๋น›์„ ํก์ˆ˜ํ•˜๊ณ , ํฐ์ƒ‰์€ ๋น›์ด ๋ฐ˜์‚ฌํ•œ๋‹ค. ์ ์™ธ์„  ์„ผ์„œ๋Š” QR์ฝ”๋“œ์˜ ํŒจํ„ด์„ ์ธ์‹ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

QR Code ๊ด€๋ จ ์ฝ”๋“œ

QR Code ์ƒ์„ฑ์— ์‚ฌ์šฉํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

์šฐ๋ฆฌ๊ฐ€ value๋กœ Props๋ฅผ ๋„˜๊ฒจ์ฃผ๊ฒŒ ๋˜๋ฉด

๋‚ด๋ถ€์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ UTF-16 ์ฝ”๋“œ๋กœ ๋งŒ๋“ค์–ด์ค€๋‹ค.

function convertStr(str: string): string {
  let out = '';
  for (let i = 0; i < str.length; i++) {
    let charcode = str.charCodeAt(i);
    if (charcode < 0x0080) {
      out += String.fromCharCode(charcode);
    } else if (charcode < 0x0800) {
      out += String.fromCharCode(0xc0 | (charcode >> 6));
      out += String.fromCharCode(0x80 | (charcode & 0x3f));
    } else if (charcode < 0xd800 || charcode >= 0xe000) {
      out += String.fromCharCode(0xe0 | (charcode >> 12));
      out += String.fromCharCode(0x80 | ((charcode >> 6) & 0x3f));
      out += String.fromCharCode(0x80 | (charcode & 0x3f));
    } else {
      // This is a surrogate pair, so we'll reconsitute the pieces and work
      // from that
      i++;
      charcode =
        0x10000 + (((charcode & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));
      out += String.fromCharCode(0xf0 | (charcode >> 18));
      out += String.fromCharCode(0x80 | ((charcode >> 12) & 0x3f));
      out += String.fromCharCode(0x80 | ((charcode >> 6) & 0x3f));
      out += String.fromCharCode(0x80 | (charcode & 0x3f));
    }
  }
  return out;
}

๊ทธ ํ›„์— ๋‚ด๋ถ€์ ์œผ๋กœ ์„ค์น˜๋œ qr.js๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ QR์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด์„œ canvas ํ˜•ํƒœ๋กœ ๋ณด์—ฌ์ค€๋‹ค.

์šฐ๋ฆฌ๋Š” ์œ„์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ QR Code๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. QR Code ์ƒ์„ฑ์— imgur์— ์˜ฌ๋ฆฐ image์˜ id๋ฅผ ๋ฐ›์•„์„œ '๋ฐฑ์—”๋“œ์ฃผ์†Œ/id' ๋ฅผ Qr Code ์ปดํฌ๋„ŒํŠธ์˜ value๋กœ ๋„˜๊ฒจ QR์ฝ”๋“œ๋กœ ๋งŒ๋“ค์—ˆ๊ณ , QR์ฝ”๋“œ๋ฅผ ์ฐ์„ ์‹œ ์šฐ๋ฆฌ ๋ฐฑ์—”๋“œ ์ฃผ์†Œ๋กœ ์ด๋™ํ•˜์—ฌ ์ด๋ฏธ์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค. save๋ฅผ ํ•  ์‹œ์—๋Š” canvas์˜ toDataUrl ๋ฉ”์†Œ๋“œ๋ฅผ ํ™œ์šฉํ•˜์—ฌ QR Code ์ด๋ฏธ์ง€ ์ž์ฒด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜์˜€๋‹ค.

import QRcode from 'qrcode.react';

...

<QRcode value={imageUrl} />