Image Test

リンク

<html>
    <head>
        <link href="https://1119s.wdfiles.com/local--code/image-test/2" rel="stylesheet">
    </head>
    <body>
        <div class="form">
            <input type="file" id="select_file" accept=".png,.jpg,.jpeg">
            <div>
                不透明度の低い画素を完全に透明にする
                <select name="min_opacity" id="min_opacity">
                    <option value="0" selected>なし</option>
                    <option value="8">8未満 (超弱)</option>
                    <option value="16">16未満 (弱)</option>
                    <option value="32">32未満 (中)</option>
                    <option value="48">48未満 (強)</option>
                    <!--<option value="-1">カスタム</option>-->
                </select>
            </div>
        </div>
        <div class="viewer">
            <div class="canvas-wrapper">
                <canvas id="canvas_in" width="400"></canvas>
                <canvas id="canvas_out" width="400"></canvas>
            </div>
            <div class="buttons">
                <div class="btn-container">
                    <button id="convert" disabled>変換</button>
                </div>
                <div class="btn-container">
                    <button id="download" disabled>保存</button>
                </div>
            </div>
        </div>
        <script type="text/javascript" src="https://1119s.wdfiles.com/local--code/image-test/3"></script>
    </body>
</html>
body {
    background: #f4f4f4;
    margin: 1em;
}
.viewer {
    background: #fff;
    border: solid 1px #ccc;
    border-radius: 12px;
    margin: 1em 1em;
    padding: 1em 1em;
    container: viewer / inline-size;
}
.canvas-wrapper {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-evenly;
    gap: 1em 1em;
 
    canvas {
        background: white;
    }
}
.buttons {
    display: flex;
    justify-content: space-evenly;
    gap: 1em;
    margin: 2em 0 1em;
 
    .btn-container {
        width: 400px;
        text-align: center;
 
        @container viewer (width < calc(800px + 1em)) {
            display: contents;
        }
    }
    button {
        display: inline-block;
        border: none;
        border-radius: 5px;
        background: #4090ff;
        color: #f8f8f8;
        font-size: 1.2em;
        width: 4em;
        padding: 0.25em;
        cursor: pointer;
 
        &:hover {
            color: #ccccff;
        }
        &[disabled] {
            background: #ccc;
            color: #555;
            cursor: not-allowed;
        }
    }
}
const sel_file = document.getElementById("select_file");
const min_opa = document.getElementById("min_opacity");
 
const canvas_in = document.getElementById("canvas_in");
const canvas_out = document.getElementById("canvas_out");
const ctx_in = canvas_in.getContext("2d");
const ctx_out = canvas_out.getContext("2d");
 
const btn_conv = document.getElementById("convert");
const btn_dl = document.getElementById("download");
 
sel_file.addEventListener("change", (e) => {
  btn_conv.disabled = false;
  btn_dl.disabled = true;
 
  var file = e.target.files[0];
  var reader = new FileReader();
 
  reader.readAsDataURL(file);
 
  reader.onload = () => {
    var dataUrl = reader.result;
    var img = new Image();
    img.src = dataUrl;
 
    img.onload = () => {
      var canvas_new_height = canvas_in.width * img.naturalHeight / img.naturalWidth; // /
      canvas_in.height = canvas_out.height = canvas_new_height;
      ctx_in.drawImage(img, 0, 0, canvas_in.width, canvas_in.height);
    }
  }
}, false);
 
btn_conv.onclick = () => {
  var imageData = ctx_in.getImageData(0, 0, canvas_in.width, canvas_in.height);
  var data = imageData.data;
 
  var min = parseInt(min_opa.value);
  for (let i = 0; i < data.length; i += 4) {
    var value = Math.max(data[i], data[i+1], data[i+2]);
    for (let j = 0; j < 3; j++) {
      data[i+j] *= 255 / value; // /
    }
    if (min == 0 || value >= min + 32) {
      data[i+3] = value;
    } else if (value >= min) {
      data[i+3] = Math.round((value - min) * (min + 32) / 32); // /
    } else {
      data[i+3] = 0;
    }
  }
 
  imageData.data = data;
  ctx_out.putImageData(imageData, 0, 0, 0, 0, canvas_out.width, canvas_out.height);
 
  btn_dl.disabled = false;
};
 
// https://qiita.com/kitasenjudesign/items/70896c91ee2492fd7449
// https://stackoverflow.com/questions/72615770/store-canvas-screenshot-to-local-filesystem-with-filesystem-api
btn_dl.onclick = () => {
  canvas_out.toBlob(async function(result) {
    const options = {
      types: [
        {
          description: 'Images',
          accept: { 'image/png': ['.png'] },
        },
      ],
      suggestedName: 'download.png',
    };
    imgFileHandle = await window.showSaveFilePicker(options);
    const writable = await imgFileHandle.createWritable();
    await writable.write(result);
    await writable.close();
 
   });
};
特に明記しない限り、このページのコンテンツは次のライセンスの下にあります: Creative Commons Attribution-ShareAlike 3.0 License