将 canvas LinearGradient 映射到图像

Mapping canvas LinearGradient to an image

function show(d) {

   function  normalize(val, max, min) { return (val - min) / (max - min); } 

   var canvas = document.createElement("canvas")
   var ctx = canvas.getContext('2d')

   let width = canvas.width = 400;
   let height = canvas.height = 400;
   let arr = d //<-- 1D array of noise data, type: float

   let gradient = ctx.createLinearGradient(25, 25, width  - 50, 25);
   gradient.addColorStop(0,   "black");
   gradient.addColorStop(0.5, "red");
   gradient.addColorStop(1,   "lime");

   ctx.fillStyle = gradient;
   ctx.fillRect(25, 25, width  - 50, 25);

     function generate(end=false) {
       let w = 50, h = 50;
       let startx = (width/2) - (w/2);
       let starty = 85;
       ctx.clearRect(startx, starty, w, h);
       ctx.strokeRect(startx, starty, w, h);
       if (end) return;
       for (let i = 0; i < w; i++)
         for (let j = 0; j < h; j++) {
           let x = i + startx;
           let y = j + starty;
           let index = i + j * w;
           let val = arr[index]
           let color = colorAt(val).join(", ")
           ctx.fillStyle = `rgba(${color})`;
           ctx.fillRect(x, y, 1, 1);
         }
     }

     generate()

     function colorAt(t) {
       t = 25 + (350 * t);
       let pixel = ctx.getImageData(t, 35, 1, 1).data;
       return [...pixel];
     }

     canvas.id     = "CursorLayer";
     canvas.style.width = '600px'
     canvas.style.height = '600px'
     canvas.style.zIndex   = 8;
     canvas.style.position = "absolute";
     canvas.style.border   = "1px solid";
     document.body.appendChild(canvas);
 }

/* create noise */
let array = []; // <-- this array is allways going to have a length of 2500
function populate(w, h) {
  for (let i = 0; i < w * h; i++)
    array[i] = Math.random();
}
 populate(50, 50) 
 show(array)

我已使用上面的代码将我的数据映射到 CanvasRenderingContext2D.createLinearGradientarr 是数据,它是一个长度为 2500 的浮点值的一维数组。长度是静态的我不想向它添加更多数据

我目前可以输出这张图片:gradientImage

如何去掉渐变条并使我想要的图像变大?不向数组添加更多数据

如果不再需要顶部的渐变条,一个简单的方法就是在使用完毕后用白色覆盖它。

最终图像的大小由 w 和 h 变量设置,此代码段将它们从 50 增加到 300,因此图像仍在 canvas 范围内。

这是您的可运行代码片段。因为我不知道你是如何设置 arr 的,所以我在评论中删除了它,只使用了一种颜色。

function show(d) {

  function normalize(val, max, min) {
    return (val - min) / (max - min);
  }

  var canvas = document.createElement("canvas")
  var ctx = canvas.getContext('2d')

  let width = canvas.width = 400;
  let height = canvas.height = 400;
  //let arr = d.attributes.position //<-- 1D array of noise data, type: float

  let gradient = ctx.createLinearGradient(25, 25, width - 50, 25);
  gradient.addColorStop(0, "black");
  gradient.addColorStop(0.5, "red");
  gradient.addColorStop(.8, "lime");

  ctx.fillStyle = gradient;
  ctx.fillRect(25, 25, width - 50, 25);

  function generate(end = false) {
    //w and h made bigger
    let w = 300,
      h = 300;
    let startx = (width / 2) - (w / 2);
    let starty = 85;
    ctx.clearRect(startx, starty, w, h);
    ctx.strokeRect(startx, starty, w, h);
    if (end) return;
    for (let i = 0; i < w; i++)
      for (let j = 0; j < h; j++) {
        let x = i + startx;
        let y = j + starty;
        let index = i + j * w;
        //let val =  normalize(arr[index],255,0)
        //let color = colorAt(val).join(", ")
        ctx.fillStyle = `rgba(255,0,,0,1)`;
        ctx.fillRect(x, y, 1, 1);
      }
  }

  generate()

  function colorAt(t) {
    t = 25 + (350 * t);
    let pixel = ctx.getImageData(t, 35, 1, 1).data;
    return [...pixel];
  }

  canvas.id = "CursorLayer";
  canvas.style.width = '600px'
  canvas.style.height = '600px'
  canvas.style.zIndex = 8;
  canvas.style.position = "absolute";
  canvas.style.border = "1px solid";

  //ADDED   
  ctx.fillStyle = 'white';
  ctx.fillRect(25, 25, width - 50, 25);

  //END OF ADDED
  document.body.appendChild(canvas);
}
show();

如果这是我的,我可能会想要两个 canvases。一个只是临时的,它会保持渐变,所以你可以在特定位置查找颜色,另一个将在最终图像绘制的地方,我会让它填满整个 canvas.