Web 检测网页图像中的图形区域

Web 检测网页图像中的图形区域,web,graphics,mouseover,webimage,Web,Graphics,Mouseover,Webimage,我一直在拐弯抹角,所以我会在这里解释我的问题,希望有人有一些想法。如下图所示: 我需要在她眼睛和嘴上的斑点上检测鼠标,并以一般形式解决这个问题。模型和Blob位于两个不同的层上,因此我可以生成一个仅包含Blob的图像,一个仅包含模型的图像,并在Blob实际悬停在模型上时,以某种方式将虚拟光标同步到Blob上 我也可以制作水滴多边形,用于命中测试,但我认为颜色命中测试会容易得多。如果我打蓝色,我在她的嘴里,我展示唇膏图像;如果我达到粉红色,我就在她的眼睛上方,并显示眼部化妆图像 这里学习者的建议

我一直在拐弯抹角,所以我会在这里解释我的问题,希望有人有一些想法。如下图所示:

我需要在她眼睛和嘴上的斑点上检测鼠标,并以一般形式解决这个问题。模型和Blob位于两个不同的层上,因此我可以生成一个仅包含Blob的图像,一个仅包含模型的图像,并在Blob实际悬停在模型上时,以某种方式将虚拟光标同步到Blob上

我也可以制作水滴多边形,用于命中测试,但我认为颜色命中测试会容易得多。如果我打蓝色,我在她的嘴里,我展示唇膏图像;如果我达到粉红色,我就在她的眼睛上方,并显示眼部化妆图像


这里学习者的建议和对话是什么?

最简单的方法是将图层图像加载到画布中,然后获取其所有像素数据。当鼠标悬停在模型图像上时,找出当前选择的颜色,如果与上一颜色不同,则触发事件以指示选择已更改

这里有一个例子,随便玩玩吧;但请注意,它并不能处理所有情况:

  • 如果图层和模型图像的大小不相同怎么办
  • 如果图层和模型图像的宽高比不相同,该怎么办
  • 如果您想使用一些alpha通道(示例中没有考虑它),该怎么办
$(函数(){
/*我们首先加载所有的图像数据*/
var-imageData=null;
var layerImage=新图像();
layerImage.onload=函数(){
var canvas=document.createElement(“canvas”);
canvas.width=this.width;
canvas.height=this.height;
context=canvas.getContext('2d');
context.drawImage(this,0,0,canvas.width,canvas.height);
imageData=context.getImageData(0,0,canvas.width,canvas.height);
};
/*例如,将图像数据设置为base64数据更容易*/
layerImage.src="数据:图片/png;base64,Ivborw0kgoaaaansuhueugaaaaaaabacayaaacqaxheaaabgdbtueaalgpc/xhbqaalwsflzaaaowgaadsibfshkgaaabp0rvh0u29mdhdhcmuaughfpbnqukvyzljuumtfh80i3aakleqvr4xu3wmq7cmawf0ixcgccgctw/xsgdwapitthkorqeqe2hbwjniwgqecbagabagabagabagabagqeqiecqecbag4e/ehmseh4wk2wkj/nqjt/nqbjt/cdzmqgzmqg3bg8qbg7cfg7cfg7c7zzzzzzzjjjjjjzzzzzzzzg7cfg7cfg7bjjj/ApfP/9Z6T87yBaUJJsVvsen9y8cDMAJ2gCWY7IHll1qaYFL84a9AelnF+CFWXylSNAGMBFLNIVE6QAMBCQ2DJQZETACRUCZQDPPEPTV9RICRAGQIAAQIECBC4NSATAGY67TVYHAAAASUVORK5CYII=“;
var pColor=null;
/*在模型图像上单击鼠标*/
$(“#模型”).mousemove(函数(事件){
/*我们修正偏移量*/
var offset=$(this.offset();
var relX=event.pageX-offset.left;
var relen=event.pageY-Math.round(offset.top);
/*然后在这个位置获取像素值(注意,我们没有保留alpha通道;它是否有价值取决于您的决定)*/
var pixelIndex=relY*layerImage.width+relX;
var dataIndex=pixelIndex*4;
var color=[imageData[dataIndex],imageData[dataIndex+1],imageData[dataIndex+2];
if(pColor==null){
/*我们在第一次进入图像时触发*/
$(this).trigger(“newColor”{
消息:“初始层颜色”,
数据:颜色
});
}else if(pColor[0]!=color[0]| | pColor[1]!=color[1]| | pColor[2]!=color[2]){
/*如果新位置是层图像中的新颜色,则触发*/
$(this).trigger(“newColor”{
消息:“更改图层颜色”,
数据:颜色
});
}
pColor=颜色;
});
/*将rgb转换为css颜色的一些小帮助*/
功能rgb2hex(红色、绿色、蓝色){

var rgb=blue |(green您可以使用SVG图形在图像上分层。 我的示例使用椭圆,但您可以同样轻松地使用多边形。 您可以使用问题中所述的颜色,也可以向svg元素添加额外的属性

示例js:

function svg_clicked(objSVG)
{
    alert(objSVG.style.fill);
    alert(objSVG.getAttribute('data-category'));
}
svg示例:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <ellipse cx="110" cy="80" rx="100" ry="50" style="fill:red;" onclick="svg_clicked(this);" data-category="lipstick" />
</svg>

这是a(将鼠标移到图片中的O上)

如果使svg元素透明(使用fill:transparent),它仍然可以工作。
您可以快速将覆盖更改为颜色或轮廓以进行测试。

如果您可以同时拥有两个图像(有斑点的图像和没有斑点的图像),我认为您可以使用HTML5画布来实现这一点

  • 正常绘制图像
  • 在主图像下方绘制水滴图像,使其不可见
  • 将blob复制到画布
  • 在mouseover上,在适当的坐标处检索画布的像素数据(R、G、B和alpha)
  • 利润
扭曲:如果您不需要它做任何其他事情,您可能只需要一个图像和它的alpha通道就可以做到这一点-给像素一个完整的不透明度(a=255),除了在BLOB 1、2和3中,它的不透明度将等于255-(1,2,3…)。不能有太多不同的斑点,否则透明度会变得明显。我没有尝试过,但它应该可以工作。考虑到“仅斑点”图像的可能压缩性,一对图像(一个没有透明度,一个也没有透明度,只有N+1颜色,PNG压缩)应该会产生更好的结果

使用jQuery或多或少地使用两个图像的伪代码(可以不使用):

var image=document.getElementById('mainImage'))
var blobs=document.getElementById('blobImage');
//创建画布
画布=$('')[0];
canvas.width=image.width;
canvas.height=image.height;
//重要提示:要使其工作,此脚本和blobImage.src必须同时为
//在同一安全域中,否则您将得到“此操作不安全”
canvas.getContext('2d').drawImage(blob,0,0,image.width,image.height);
//现在等着吧。
$('#main image').mouseover(函数(事件){
//要执行的操作:在主图像上按边距偏移clientX、clientY
var ctx=画布。
var image  = document.getElementById('mainImage')
var blobs  = document.getElementById('blobImage');

// Create a canvas
canvas = $('<canvas/>')[0];
canvas.width = image.width;
canvas.height = image.height;
// IMPORTANT: for this to work, this script and blobImage.src must be both
// in the same security domain, or you'll get "this operation is insecure"
canvas.getContext('2d').drawImage(blobs, 0, 0, image.width, image.height);

// Now wait for it.
$('#mainImage').mouseover(function(event) {
    // TO DO: offset clientX, clientY by margin on mainImage
    var ctx = canvas.getContext('2d');
    // Get one pixel
    var pix = ctx.getImageData(event.clientX, event.clientY, 1, 1);
    // Retrieve the red component
    var red = pix.data[0];
    if (red > 128) {
        // ... do something for red
    }
});