使用Javascript合并图像

54

是否可以使用JavaScript合并图片?

例如,如果你有两个尺寸相同的矩形.jpg或.png图像文件,是否可以将它们侧向对齐,并生成新的.jpg或.png图像文件的合并副本?

5个回答

74

您可以使用JavaScript将它们合并为一个画布,然后将该画布转换为图像。

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var imageObj1 = new Image();
var imageObj2 = new Image();
imageObj1.src = "1.png"
imageObj1.onload = function() {
   ctx.drawImage(imageObj1, 0, 0, 328, 526);
   imageObj2.src = "2.png";
   imageObj2.onload = function() {
      ctx.drawImage(imageObj2, 15, 85, 300, 300);
      var img = c.toDataURL("image/png");
      document.write('<img src="' + img + '" width="328" height="526"/>');
   }
};

出于安全考虑,您的两个图像必须与 JavaScript 文件位于同一个域中 (例如 http://123.com/1.png, http://123.com/2.pnghttp://123.com/script.js),否则函数 toDataURL() 将会出错。


1
示例在codepen上。 - ashleedawg

26

更新至2019/2020+: 现在有一个很棒的npm包叫做merge-images,可以用来实现这个功能。

而且它的使用非常简单!

import mergeImages from 'merge-images';
 
mergeImages(['/body.png', '/eyes.png', '/mouth.png'])
  .then(b64 => document.querySelector('img').src = b64);
  // data:image/png;base64,iVBORw0KGgoAA...

您可以使用定位、透明度(每个图像都可以)和输出尺寸进一步自定义它!

(我与此软件包无关,只是浪费了3天时间使html2canvas正常工作,然后找到了这个救星!)


1
有没有不使用Node.js的纯JS版本? - lovechillcool
@lovechillcool 您可以在浏览器中使用 merge-images 包。如果您没有可用的 npm,您可以通过脚本标签包含它:<script src="https://unpkg.com/merge-images"></script> - Node.js 在此不是必需的。 - kano
我已经尝试过了。但是一直出现CORS错误。 - lovechillcool
我希望我能将base64图像传递到源数组中......我想我的网络摄像头功能会更好。 - Vipertecpro
哇!这个库救了我的命。 - Peter Utekal
显示剩余3条评论

11

Huỳnh Quốc Phong部分正确:

您可以使用Canvas合并图像。但它们可以来自其他域。只需在您的dom中加载图片。 一旦图片加载完成(可以使用JavaScript检查,见下文),您就可以在Canvas中使用它们。

var canvas = canvasBuild.getContext('canvasObj');
var img = document.getElementById('mergePic1');
canvas.drawImage(img, 0, 0);

为了检查图像是否已加载,我建议使用jQuery插件http://desandro.github.io/imagesloaded/ - 但也可以不使用。


7

我知道这是一篇旧文章,但我自己搜索解决此问题时也遇到了它。更重要的是,我希望能够上传应该使用的图片(而不需要依赖服务器端逻辑)。

我创建了一个基于此的fiddle (http://jsfiddle.net/davidwalton/4pjreyfb/6/):

如何使用Javascript/HTML进行简单的图像上传

然后我添加了胡英国丰上面的逻辑 (使用Javascript合并图像):

HTML:

<input class="file1" type="file" data-image-selector=".image1" />
<input class="file2" type="file" data-image-selector=".image2" />
<br />
<img class="image1 hidden" alt="medium image 1" />
<img class="image2 hidden" alt="medium image 2" />
<br />
<input class="btn-merge" type="button" value="Merge!" />
<br />
<img class="merged-image hidden" alt="merged image" />
<canvas id="canvas" class="hidden"></canvas>

JS:

$('.file1, .file2').on('change', function() {
  var reader = new FileReader(),
    imageSelector = $(this).data('image-selector');

  if (this.files && this.files[0]) {
    reader.onload = function(e) {
      imageIsLoaded(e, imageSelector)
    };
    reader.readAsDataURL(this.files[0]);
  }
});

$('.btn-merge').on('click', merge);

function imageIsLoaded(e, imageSelector) {
  $(imageSelector).attr('src', e.target.result);
  $(imageSelector).removeClass('hidden');
};

function merge() {
  var canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d'),
    imageObj1 = new Image(),
    imageObj2 = new Image();

  imageObj1.src = $('.image1').attr('src');
  imageObj1.onload = function() {
    ctx.globalAlpha = 1;
    ctx.drawImage(imageObj1, 0, 0, 328, 526);
    imageObj2.src = $('.image2').attr('src');;
    imageObj2.onload = function() {
      ctx.globalAlpha = 0.5;
      ctx.drawImage(imageObj2, 15, 85, 300, 300);
      var img = canvas.toDataURL('image/jpeg');
      $('.merged-image').attr('src', img);
      $('.merged-image').removeClass('hidden');
    }
  };
}

此外,它还使用了一些透明度,以允许使用两个JPEG文件。

请注意,所有图像的定位和大小都是通过ctx.drawImage()函数来管理的。演示可能不太美观,但它应该证明这个概念。 :)

希望这对你有所帮助!


-13

不,你不能这样做。

通过一些 CSS/HTML 魔法,你可以让它们 合并 显示。


如果你想要将它们真正合并在一起,我建议使用 Photoshop。
或者你可以编写一些服务器代码来创建和合并图像。

7
这是错误的,因为得到更高投票的答案表明了这一点。 - Ivan Durst
1
从技术上讲,有多个JavaScript环境。上面的作者正在使用DOM的API来操作图像。 如果使用纯JavaScript或Node进行操作,则情况就不同了。 - Dave Voyles
@DaveVoyles Node拥有Node的库(快速搜索找到了Sharp,看起来很有前途)。至于“纯”JavaScript,现在除非你是绝对的疯子,否则“纯”任何语言都不会让你走得太远,这在技术上可以使用任何图灵完备的语言完成 :) - Imperishable Night

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接