PPIL

Pixel Place Image Loader

目前为 2022-05-08 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/443894/1048499/PPIL.js

// ==UserScript==
// @name         PPIL
// @description  Pixel Place Image Loader
// @version      1.3
// @author       0vC4
// @namespace    https://gf.qytechs.cn/users/670183
// @match        https://pixelplace.io/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=pixelplace.io
// @license      MIT
// @grant        none
// @run-at       document-start
// ==/UserScript==



const PPIL = (() => {
  if (window.PPIL) return window.PPIL;



  const worker = function(func) {
      const worker = new Worker(URL.createObjectURL(new Blob(["onmessage=async({data})=>self.postMessage(await(" + func.toString() + ")(data))"], { type: "text/javascript" })));
      const root = {};
      const post = data => (worker.postMessage(data), root);
      const then = callback => (worker.onmessage=({data})=>callback(data), root);
      return Object.assign(root, {post, then});
  };



  const PPIL = {};
  PPIL.loadImage = (w, h) => callback => {
      const dropArea = document.createElement('div');
      top.document.body.appendChild(dropArea);
      dropArea.style = "width: calc(100% - 2em);height: calc(100% - 2em);position: fixed;left: 0px;top: 0px;background-color: rgba(0, 0, 0, 0.533);z-index: 9999;display: flex;color: white;font-size: 48pt;justify-content: center;align-items: center;border: 3px white dashed;border-radius: 18px;margin: 1em;";
      dropArea.textContent = "Drop Image";
      dropArea.onclick = e => dropArea.remove();

      ['dragenter','dragover','dragleave','drop'].forEach(eName =>
          dropArea.addEventListener(eName, e => {
              e.preventDefault();
              e.stopPropagation();
          }, false)
      );

      dropArea.addEventListener('drop', e => {

          const reader = new FileReader();
          reader.readAsDataURL(e.dataTransfer.files[0]);
          reader.onload = e => {

              const img = new Image;
              img.src = reader.result;
              img.onload = e => {
                  let {width, height} = img;
                  if (w != null) width = w;
                  if (h != null) height = h;
                  const canvas = document.createElement('canvas');
                  canvas.width = width;
                  canvas.height = height;
                  const ctx = canvas.getContext('2d');
                  ctx.drawImage(img, 0, 0, width, height);
                  const rgba = ctx.getImageData(0, 0, width, height).data;

                  worker(async ({rgba, width, height}) => {
                      const zero = 0xCCCCCC;

                      const palette = new Uint32Array([
                          0xFFFFFF,
                          0xC4C4C4,
                          0x888888,
                          0x555555,
                          0x222222,
                          0x000000,
                          0x006600,
                          0x22B14C,
                          0x02BE01,
                          0x51E119,
                          0x94E044,
                          0xFBFF5B,
                          0xE5D900,
                          0xE6BE0C,
                          0xE59500,
                          0xA06A42,
                          0x99530D,
                          0x633C1F,
                          0x6B0000,
                          0x9F0000,
                          0xE50000,
                          0xFF3904,
                          0xBB4F00,
                          0xFF755F,
                          0xFFC49F,
                          0xFFDFCC,
                          0xFFA7D1,
                          0xCF6EE4,
                          0xEC08EC,
                          0x820080,
                          0x5100FF,
                          0x020763,
                          0x0000EA,
                          0x044BFF,
                          0x6583CF,
                          0x36BAFF,
                          0x0083C7,
                          0x00D3DD,
                          0x45FFC8
                      ]);

                      const exclude = new Uint32Array([
                          0x51E119,
                          0xFF3904,
                          0x5100FF,
                          0x45FFC8
                      ]);

                      const filtered = [...palette.map(p => exclude.includes(p) ? zero : p)].filter(p => p != zero).map(clr => [(clr>>16)&0xFF, (clr>>8)&0xFF, clr&0xFF]);

                      const toPixel = (r2, g2, b2) => palette.indexOf(
                          filtered
                          .map(([r, g, b]) => [
                              ((r2 - r)*.299)**2 +
                              ((g2 - g)*.587)**2 +
                              ((b2 - b)*.114)**2,
                              (r<<16) + (g<<8) + b
                          ])
                          .sort((a,b) => a[0]-b[0])[0][1]
                      );

                      const pixels = new Uint8Array(rgba.length>>2);
                      for (let i = 0; i < rgba.length; i += 4)
                          pixels[i>>2] = rgba[i+3] >= 0xAA ? toPixel(rgba[i], rgba[i+1], rgba[i+2]) : -1;

                      return [pixels, width, height];

                  })
                  .then(callback)
                  .post({rgba,width,height});
              };
          };

          dropArea.remove();
      },false);
  };



  window.PPIL = PPIL;
  return PPIL;
})();
// 0vC4#7152

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址