<input type=file>からQRコードをスキャン【jsQR】

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="LYMpzea" data-user="04" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/04/pen/LYMpzea">
  scan QR code from &lt;input type=file&gt;</a> by John Doe (<a href="https://codepen.io/04">@04</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

```javascript
async function scanQRFromFile(file) {
  const img = new Image();
  img.src = URL.createObjectURL(file);
  await new Promise((resolve) => img.addEventListener("load", resolve));
  const canvas = document.createElement("canvas");
  canvas.width = img.naturalWidth;
  canvas.height = img.naturalHeight;
  const ctx = canvas.getContext("2d");
  ctx.imageSmoothingEnabled = false;
  ctx.drawImage(img, 0, 0);
  const imageData = ctx.getImageData(0, 0, img.naturalWidth, img.naturalHeight);
  return jsQR(imageData.data, img.naturalWidth, img.naturalHeight)?.data;
}

document.querySelector("input").addEventListener("change", async (e) => {
  const code = await scanQRFromFile(e.target.files[0]);
  document.write(code);
});
```

<details><summary>OffscreenCanvasを使う場合</summary>

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="xxmwXNe" data-user="04" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/04/pen/xxmwXNe">
  scan QR code from &lt;input type=file&gt;</a> by John Doe (<a href="https://codepen.io/04">@04</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

```javascript
async function scanQRFromFile(file) {
  const img = new Image();
  img.src = URL.createObjectURL(file);
  await new Promise((resolve) => img.addEventListener("load", resolve));
  const canvas = new OffscreenCanvas(img.naturalWidth, img.naturalHeight);
  const ctx = canvas.getContext("2d");
  ctx.imageSmoothingEnabled = false;
  ctx.drawImage(img, 0, 0);
  const imageData = ctx.getImageData(0, 0, img.naturalWidth, img.naturalHeight);
  return jsQR(imageData.data, img.naturalWidth, img.naturalHeight)?.data;
}

document.querySelector("input").addEventListener("change", async (e) => {
  const code = await scanQRFromFile(e.target.files[0]);
  document.write(code);
});
```
</details>

<details><summary>QR画像の周りにパディングとホワイト背景をつける場合</summary>

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="WNLrNPg" data-user="04" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/04/pen/WNLrNPg">
  scan QR code from &lt;input type=file&gt; with OffscreenCanvas</a> by John Doe (<a href="https://codepen.io/04">@04</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

```javascript
import jsQR from "https://cdn.skypack.dev/jsqr@1.4.0";

async function scanQRFromFileWithPaddingAndWhiteBackground(file, padding = 32) {
  const img = new Image();
  img.src = URL.createObjectURL(file);
  await new Promise((resolve) => img.addEventListener("load", resolve));
  const width = img.naturalWidth + padding * 2;
  const height = img.naturalHeight + padding * 2;
  const canvas = new OffscreenCanvas(width, height);
  const ctx = canvas.getContext("2d");
  ctx.imageSmoothingEnabled = false;
  ctx.fillStyle = "white";
  ctx.fillRect(0, 0, width, height);
  ctx.drawImage(img, padding, padding);
  const imageData = ctx.getImageData(0, 0, width, height);
  return jsQR(imageData.data, width, height)?.data;
}

document.querySelector("input").addEventListener("change", async (e) => {
  const code = await scanQRFromFileWithPaddingAndWhiteBackground(e.target.files[0]);
  document.write(code);
});
```
</details>

<details><summary>画像を貼り付ける場合</summary>

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="rNoOYao" data-user="04" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/04/pen/rNoOYao">
  scan QR code from &lt;input type=file&gt; with Ctrl + V</a> by John Doe (<a href="https://codepen.io/04">@04</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

```javascript
async function scanQRFromFile(file) {
  const img = new Image();
  img.src = URL.createObjectURL(file);
  await new Promise((resolve) => img.addEventListener("load", resolve));
  const canvas = new OffscreenCanvas(img.naturalWidth, img.naturalHeight);
  const ctx = canvas.getContext("2d");
  ctx.imageSmoothingEnabled = false;
  ctx.drawImage(img, 0, 0);
  const imageData = ctx.getImageData(0, 0, img.naturalWidth, img.naturalHeight);
  return jsQR(imageData.data, img.naturalWidth, img.naturalHeight)?.data;
}

addEventListener("paste", async (e) => {
  const code = await scanQRFromFile(e.clipboardData.files[0]);
  document.write(code);
});
```
</details>


https://github.com/cozmo/jsQR/issues/215