首页 > 解决方案 > 将 IF 条件添加到可点击图像以确定像素值

问题描述

我们从 JSON 中获取了 2 张图像:

1.蒙版图片[名称以蒙版_开头]

2.汽车图片[名称开头不是mask_ ]

在此处输入图像描述

要求

onclick蒙版图片,我想显示文件上传对话框。它工作正常。但是onclick汽车图像,我不想显示文件上传对话框。

问题

onclick显示汽车图像,文件上传对话框。但是汽车图片不应该是可点击的,因为它的名字以“other than mask_”开头

我试过$('.masked-img').css('pointer-events', 'none');了,但它没有帮助我。

以下是片段:

var target;
const imageUrl = "https://i.imgur.com/RzEm1WK.png";

let jsonData = {
  "layers": [{
    "x": 0,
    "height": 612,
    "layers": [{
        "x": 70,
        "src": "ax0HVTs.png",
        "y": 199,
        "height": 296,
        "width": 429,
        "name": "mask_1"
      },
      {
        "name": "car",
        "x": 25,
        "src": "iEA642D.jpg",
        "height": 324,
        "width": 471,
        "y": 22

      }
    ],
    "y": 0,
    "width": 612
  }]
};

const containerElement = $('#container');
const fileUp = $('#fileup');
let mask;

$(function() {
  // Upload image onclick mask image 
  containerElement.click(function(e) {
    var res = e.target;
    target = res.id;
    if (e.target.getContext) {
      // click only inside Non Transparent part 
      var pixel = e.target.getContext('2d').getImageData(e.offsetX, e.offsetY, 1, 1).data;
      if (pixel[3] === 255) {
        setTimeout(() => {
          $('#fileup').click();
        }, 20);
      }
    }
  });

  // Fetch mask images from json file - IGNORE this code 

  function getAllSrc(layers) {
    let arr = [];
    layers.forEach(layer => {
      if (layer.src) {
        arr.push({
          src: layer.src,
          x: layer.x,
          y: layer.y,
          height: layer.height,
          width: layer.width,
          name: layer.name
        });
      } else if (layer.layers) {
        let newArr = getAllSrc(layer.layers);
        if (newArr.length > 0) {
          newArr.forEach(({
            src,
            x,
            y,
            height,
            width,
            name
          }) => {
            arr.push({
              src,
              x: (layer.x + x),
              y: (layer.y + y),
              height,
              width,
              name: (name)
            });
          });
        }
      }
    });
    return arr;
  }

  function json(data) {
    var width = 0;
    var height = 0;

    let arr = getAllSrc(data.layers);
    let layer1 = data.layers;
    width = layer1[0].width;
    height = layer1[0].height;
    let counter = 0;
    let table = [];

    // container dimensions 
    containerElement.css('width', width + "px").css('height', height + "px").addClass('temp');
    //end 

    for (let {
        src,
        x,
        y,
        name
      } of arr) {

      //Get Height and width of mask image [ edit button ] 
      var ImagePosition = arr;
      //code end 


      var imageUrl1 = imageUrl;


      var mask = $(".container").mask({
        imageUrl: name.indexOf('mask_') !== -1 ? imageUrl1 : undefined,

        // Fetch Mask images 
        maskImageUrl: 'http://i.imgur.com/' + src,
        // end 

        onMaskImageCreate: function(img) {
          // Mask image positions 
          img.css({
            "position": "absolute",
            "left": x + "px",
            "top": y + "px"
          });
          // end 

        },
        id: counter
      });
      // here 
      table.push(mask);
      fileup.onchange = function() {

        let mask2 = table[target];
        const newImageLoadedId = mask2.loadImage(URL.createObjectURL(fileup.files[0]));
        document.getElementById('fileup').value = "";

      };
      counter++;
    }
    return mask;
  }
  mask = json(jsonData);
}); // end of function 

// Image code 

(function($) {
  window.JQmasks = [];
  $.fn.mask = function(options) {
    // This is the easiest way to have default options. 
    var settings = $.extend({
      // These are the defaults. 
      maskImageUrl: undefined,
      imageUrl: undefined,
      scale: 1,
      id: new Date().getUTCMilliseconds().toString(),
      x: 0, // image start position 
      y: 0, // image start position 
      onMaskImageCreate: function(div) {},
    }, options);

    // Create the image properties
    settings.maskImage = new Image
    settings.image = new Image

    // set the cross-origin attributes
    settings.maskImage.setAttribute('crossOrigin', 'anonymous');
    settings.image.setAttribute('crossOrigin', 'anonymous');

    settings.maskImage.onload = function() {
      // once the mask is loaded, load the image
      container.loadImage(settings.imageUrl)
      container.drawMask()
    }

    settings.image.onload = function() {
      // once the image is loaded, render to canvas

      container.drawImage()
    }

    var container = $(this);

    let prevX = 0,
      prevY = 0,
      draggable = false,
      img,
      canvas,
      context,
      image,
      timeout,
      initImage = false,
      startX = settings.x,
      startY = settings.y,
      div;

    container.drawMask = function() {
      if (!settings.maskImage) return true;
      canvas.width = settings.maskImage.width;
      canvas.height = settings.maskImage.height;
      context.save();
      context.beginPath();
      context.globalCompositeOperation = "source-over";
      // draw the masked image after scaling 
      if (settings.maskImage) context.drawImage(settings.maskImage, 0, 0, settings.maskImage.width, settings.maskImage.height);
      context.restore()
    };

    container.drawImage = function() {

      const img = settings.image

      settings.x = (canvas.width - (img.width * settings.scale)) / 2
      settings.y = (canvas.height - (img.height * settings.scale)) / 2

      context.globalCompositeOperation = 'source-atop';
      if (img) context.drawImage(img, settings.x, settings.y, img.width * settings.scale, img.height * settings.scale);
      context.restore()
      initImage = false;
    }

    // change the draggable image 

    container.loadImage = function(imageUrl) {
      if (!imageUrl) return true;
      settings.y = startY;
      settings.x = startX;
      prevX = prevY = 0;

      initImage = true;

      settings.image.src = imageUrl; // CHANGED

      // sirpepole Add this 
      return settings.id;
    };

    container.loadMaskImage = function(imageUrl, from) {

      canvas = document.createElement("canvas");
      context = canvas.getContext('2d');
      canvas.setAttribute("draggable", "true");
      canvas.setAttribute("id", settings.id);
      // settings.maskImageUrl = imageUrl;
      settings.maskImage.src = imageUrl // CHANGED

      div = $("<div/>", {
        "class": "masked-img"
      }).append(canvas);

      // div.find("canvas").on('touchstart mousedown', function(event) 
      div.find("canvas").on('dragstart', function(event) {
        if (event.handled === false) return;
        event.handled = true;
        container.onDragStart(event);
      });

      div.find("canvas").on('touchend mouseup', function(event) {
        if (event.handled === false) return;
        event.handled = true;
        container.selected(event);
      });

      div.find("canvas").bind("dragover", container.onDragOver);

      container.append(div);
      if (settings.onMaskImageCreate)
        settings.onMaskImageCreate(div);

      // container.loadImage(settings.imageUrl);
      // Moved this to the settings.maskImage.onload
    };
    if (settings.maskImageUrl) {
      container.loadMaskImage(settings.maskImageUrl);
    }
    JQmasks.push({
      item: container,
      id: settings.id
    })
    // Edit image 
    div.addClass('masked-img' + settings.id);
    div.attr('data-id', settings.id);
    // ends 
    return container;
  };
}(jQuery));
.container {
  background: silver;
  position: relative;
}

.container img {
  position: absolute;
  top: 0;
  bottom: 250px;
  left: 0;
  right: 0;
  margin: auto;
  z-index: 999;
}

.masked-img {
  overflow: hidden;
  position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="fileup" name="fileup" type="file" style="display:none" />
<div id="container" class="container"></div>

这是pastebin 中的CodepenFiddle完整代码

我们实现了类似的功能,即仅在蒙版图像上显示“+”图标......

标签: javascriptjqueryhtml5-canvas

解决方案


您正在获取一个像素的数据,它返回一个 4 字节长的 Uint8ClampedArray。

var pixel = e.target.getContext('2d').getImageData(e.offsetX, e.offsetY, 1, 1).data;

现在这 4 个字节代表像素的 R、G、B 和 A 值。表示 Alpha 值,对于大多数图像来说,pixels[3]它很容易达到 255。

如果您想确保只有白色像素应该触发动作,您应该检查 R、G 和 B 是否为 255。

if (pixel[0] === 255 && pixel[1] === 255 && pixel[2] === 255) {
     setTimeout(() => {
         $('#fileup').click();
     }, 20);
}

暗示:

您的程序存在设计缺陷。也就是说,如果您的图像(汽车或任何东西)具有白色像素并且用户单击其中一个像素,则会采取行动。您应该检查蒙版区域上的点击,然后查找白色像素。


推荐阅读