【问题标题】:javascript, replace specific colored area on image by other imagejavascript,用其他图像替换图像上的特定颜色区域
【发布时间】:2018-01-19 19:56:25
【问题描述】:

我一直在网上搜索以解决我的问题,但我开始认为我没有以正确的方式进行搜索。

假设我有下面的图片,我想做的是用用户上传的图片替换蓝色区域,但我不知道该怎么做。

我找到的最接近的是this,但这是绘制一个红色矩形,其中给出了特定坐标,我需要(我认为)是查找/检测这些坐标并替换他们用图像。 有没有人遇到过这个?你能为我指出正确的方向吗?真的卡在这里了!

注意:我放在这里的图像只是为了问题的目的,这不是我的图像。 感谢您的时间,问候

编辑:

好的,我应该首先将代码放在这里,为此我深表歉意,正如我之前所说,这是我正在使用 phonegap 和 jquery mobile 做的应用程序,该应用程序使用底部的导航栏,其中一个页面称为“预览”,这是我需要图像功能才能工作的地方,但我错过了一些东西,我认为是缺乏知识:

我的 index.html:

 <div data-role="page" data-url="preview" id="preview">
      <div data-role="header" style="background-color: rgb(182, 202, 51)" data-position="fixed">
        <h1 id="titlePreview">PREVIEW</h1>
        <a href="#language" id="langBtn" style="width: 20px;height: 20px; background:none;  " href="#" data-icon="comment" data-iconpos="notext" class="ui-btn-left"></a>
      </div>
        <div id="previewSaco" class="containerPreviewSaco">//if i remove this div, the navbar on the bottom disapears. 
          <canvas id="myCanvas" width="200" height="200">//i´m testing with this size, but yes the image is supose to have a 100% with, in fact the image as 1940x2372. 
       </div>
      <div data-role="footer" data-position="fixed">
        <div data-role="navbar" class="ui-bar">
          <ul>
            //in here i have my several "li" for navegation and i think it´s irrelevant for my question.
          </ul>
        </div>
      </div>
    </div>

我的 .js 文件:

$(document).on("click", "#btnPreview", function (event) {

    var ctx = document.getElementById('myCanvas').getContext('2d');

    var img = new Image;
    img.onload = function(){
      ctx.drawImage(img,0,0);
      img2.src = 'img/capa.png'; 
    };

    var img2 = new Image;
    img2.onload = function(){
        ctx.globalCompositeOperation = 'destination-over';

      //ctx.scale(x, y);
      //ctx.rotate(angle);
      //ctx.translate(x, y);

      //or

      //ctx.transform(a, b, c, d, e, f);

      ctx.drawImage(img2,0,0);
    };

    var uri1 = 'img/previewSaco1.png'; //this is the main image, which is suppose to load when i click in the page "preview", **and it´s not happening** and i have create the transparent area to were the uploaded image by the user is also suppose to go.

    var uri2 = 'img/capa.png';//this image is a dummy logo to test in the bigger image
    img.src = uri1;
});

注意:当我运行应用程序时,phonegap 桌面总是这样说:未定义的内容安全策略已修改为:https://ssl.gstatic.com;style-src' self' 'unsafe-inline' 数据:blob:;media-src *;img-src * 'self' 数据:content:;script-src * 'unsafe-inline' 'unsafe-eval' 数据:blob:;">

【问题讨论】:

  • 您必须遍历画布图像的各个像素,并检查它们的颜色。您可能不想使用一个固定的颜色值,而是实现某种阈值。如果像素符合您的替换标准,那么您可以从另一张图像中获得相应的像素值......当然,这需要两个图像具有相同的尺寸,否则您必须先定义如何处理这种情况最重要的是(放大/缩小其中一个图像以匹配另一个,这也可能会拉伸/扭曲它,或者仅将过程应用于有限的部分,...)
  • 您是否受限于任何浏览器的任何版本?另外,您是否可以选择在后端服务中处理图像?
  • 你能用 alpha 蒙版图像覆盖图像吗?还是您需要将最终图像设为包含所有数据的 1 张图像?
  • 我有一个解决方案,我只是不确定它是否跨浏览器,我正在完成笔,给我几分钟。
  • 谢谢大家的回复,我忘了说这是一个应用程序,我也在使用phonegap,我不知道这是否会影响...... Lars-Kristian Johansen,是的!我们的目标是只把它变成一张图片。

标签: javascript html css html5-canvas


【解决方案1】:

你可以使用Context2D.globalCompositeOperation = 'destination-over'; 在此处阅读更多信息GlobalCompositeOperation

首先在编辑器中打开您的图像。剪下要替换的区域。 (使像素透明)。现在加载图像并将其写入画布。

然后加载您要放入的图像。 设置ctx.globalCompositeOperation = 'destination-over'; 并将图像写入画布。

您还可以在第二次写入操作之前在画布上设置变换以更好地适应图像。

示例:jsfiddle.net

编辑 1: 加载第一张图片后,您可以根据颜色设置透明度。 检查this answer

【讨论】:

  • 嗨 Lars,我一直在使用您在该 jsfiddle 中提供的代码,如果我在这些步骤上感到厌烦,请纠正我:我打开了我的 Photoshop 并在我想要的区域创建了透明度第二张图片出现,然后我去了我的代码编辑器,尝试了你提供的代码,但我必须找到图片的 uri,所以我去了这里(dataurl.net/#dataurlmaker)并复制了图片的 uri,但是当我尝试在我的编辑器中过去的代码,它显示为黑色,我知道这是一个菜鸟问题,但有什么问题?问候
  • 首先你不需要使用data-uri,(我用它来嵌入sn-p)。我建议您以更优化的方式加载图像。只需将图像 src 设置为适用于您的设置的路径。没有看到任何代码就很难知道,但这可能会有所帮助。确保图像加载。在 onload 处理程序中执行几个console.log(img)。或者使用调试工具中的网络选项卡,图像应该在那里可见。示例中的画布大小仅为 200x200px,也许您使用的是非常大的图像?
  • 嗨 Lars,我已经编辑了我的问题,并且我已经放置了代码,你能帮我吗?谢谢和问候
【解决方案2】:

好的,我们开始:

将其用作 HTML 结构:

<div id="imageContainer" class="center">
<h2>Lets go and see how it goes</h2>
<img class="pic" src="https://moltopiccolo.files.wordpress.com/2012/01/cool-
drinks.jpg"> 
</div>

你可以在容器div上设置任何bg图像,这个不会改变。

图片使用CSS剪辑路径,它需要很多前缀,但看起来很棒,你可以给你的图片任何形状,在线有剪辑路径生成器,你甚至可以动画剪辑路径。

我是这样的:

#imageContainer img {
-webkit-clip-path: polygon(1% 3%, 3% 9%, 18% 21%, 54% 20%, 83% 63%, 66% 76%, 
15% 83%, 25% 45%);
clip-path: polygon(17% 13%, 33% 9%, 58% 21%, 84% 20%, 83% 63%, 66% 76%, 15% 
83%, 25% 45%);
-webkit-transition: -webkit-clip-path .6s ease-out;
transition: -webkit-clip-path .6s ease-out;
position:absolute;
border-radius: 5px;
width: 100%;
height:270px;

}

现在我做了一个文件上传的输入按钮,以及下面的JS函数:

var getval = document.querySelector("#getval");

getval.addEventListener("change", previewFile);

function previewFile() {
var reader = new FileReader();
var bgImage = document.querySelector(".pic");
var file = document.querySelector("input[type=file]").files[0];
reader.onloadend = function() {
bgImage.src = reader.result;
};

if (file) {
reader.readAsDataURL(file); //reads the data as a URL
 } else {
file.src = "";
}
}

这是链接

https://codepen.io/damianocel/pen/KdobyK

【讨论】:

  • 非常感谢!!!! ptts,这让我很远很远,但我有一个问题,在这个解决方案中,您正在绘制将替换图像的形状,对吗?我的问题是,有没有一种方法可以不绘制形状而是检测形状(它的坐标、区域等),然后用图像替换该区域。
  • @Japa,不客气。检测形状会使这件事变得非常复杂。但这几乎没有必要,因为您可以自己选择形状,只需生成剪辑路径即可。我只会接受常规的图片形状,如果你考虑一下,twitter,pinterest 等,他们都不关心上传的形状,你比他们更灵活。您可以为用户提供不同路径/形状的选择。形状不是完全绘制的,它是预先设置的,只需检查 css 文件,悬停状态和正常状态的图像 css。您可以选择任何默认值。
猜你喜欢
  • 1970-01-01
  • 2015-01-25
  • 2015-04-28
  • 1970-01-01
  • 2021-04-30
  • 1970-01-01
  • 2013-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多