是否可以将多个图像层收集到一个画布中?

时间:2019-09-09 15:46:55

标签: javascript html5-canvas

我有一个div,其中固定了几张图像,这些图像要放在一张画布上,以便保存合成图片。这可能吗?

我阅读了w3schools的画布教程,并检查了带有MDN的API,并想出了下面的代码,什么都不做...

<div id="pics" >
<img id="i1" class="images"
src="http://chris.chrisjneeds.com/images/stars/stars01.jpg" width="300" height="277" style="position: fixed;">
<img id="i2" class="images" 
src="http://chris.chrisjneeds.com/images/ships/ships26.png" width="300" height="277" style="position: fixed;">
</div>

<canvas id="myCanvas" width="250" height="300"
style="border:1px solid #d3d3d3; horizontal-align: right; float: right">
Your browser does not support the HTML5 canvas tag.</canvas>

<script>
function myCanvas() {
var aImages = document.getElementsByClassName('images'),
      nImgsLen = aImages.length;
var oCanvas = document.getElementById("myCanvas");
var oCtx = oCanvas.getContext("2d");

for (var oImgData, nImgId = 0; nImgId < nImgsLen; nImgId++) {
  oImgData = oCtx.getImageData(0, 0, 300, 277); 
  oCtx.putImageData(oImgData, 0, 0);
}
var img=new Image();
img.src = oCanvas.toDataURL();
oCtx.drawImage(img,10,10);

}

我期望画布中有合成图像,但到目前为止我什么都没得到。请帮助

2 个答案:

答案 0 :(得分:2)

当然可以,但不是 这样的方式。

getImageData / putImageData方法适用于pixel manipulation,对您的问题绝对没有用。您的代码只是将刚刚创建的画布区域复制到自身中(即不执行任何操作)。但是,您真正需要的是使用drawImage方法将图像一张一张地绘制到画布上。还要注意,您不需要使用toDataURL方法(它主要用于发送/保存图像),因为您通过drawImage调用后,画布中已经需要合成图像。

因此您的代码应如下所示:

...
var aImages = document.getElementsByClassName('images');
var oCanvas = document.getElementById("myCanvas");
var oCtx = oCanvas.getContext("2d");
for (var img of aImages) {
  oCtx.drawImage(img, 0, 0, img.width, img.height);
}

答案 1 :(得分:0)

我的问题的第二部分是“以便我可以保存合成图片”

这是我从HOW TO SAVE AN IMAGE TO DISK FROM A CANVAS中找到的

这是完整的代码(希望对您有所帮助)

function getImgs4Canvas() {
    var aImages=$("#cloneimages img");
    var oCanvas = document.getElementById("imgCanvas");
    var oCtx = oCanvas.getContext("2d");
    for (var oimg of aImages) {
        oCtx.drawImage(oimg, 0, 0, oimg.width, oimg.height);
    }
    var jpgFile = oCanvas.toDataURL('image/jpeg', 1.0);
    // save the image as a jpg 'blob' in the user's download (default) directoy
    ImageSaver.download_data_uri(jpgFile, "downloadimgtest");
}

var ImageSaver = {
    // function to force-download from a data uri as a filename
    // NB the download="filename" attribute isn't yet supported by safari
    download_data_uri: function(dataURI, fileName) {
        var tempUrl = ImageSaver.make_url_from_data(dataURI);
        var link = $('<a href="' + tempUrl + '" id="download" download="' + fileName + '" target="_blank"> </a>');
        $("body").append(link);
        $("#download").get(0).click();
    },

    // function to generate a temporary browser index url for a datauri
    // if a data-uri is larger than 2mb, chrome's address bar can't handle it.
    // fortunately, you can blob it and then use a temporary blob url
    make_url_from_data: function(dataURI) {
        var blob = ImageSaver.make_blob(dataURI);
        var tempUrl = URL.createObjectURL(blob);
        return tempUrl;
    },

    // function to convert a datauri to a blob
    // Blobs are temporary data structures that can hold binary data, and make that data accessible through a short url. They can probably do other things too; I have no idea.
    make_blob: function(dataURI) {
        // convert base64 to raw binary data held in a string
        // doesn't handle URLEncoded DataURIs
        var byteString;
        if (dataURI.split(',')[0].indexOf('base64') >= 0)
            byteString = atob(dataURI.split(',')[1]);
        else
            byteString = unescape(dataURI.split(',')[1]);
        // separate out the mime component
        var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

        // write the bytes of the string to an ArrayBuffer
        var ab = new ArrayBuffer(byteString.length);
        var ia = new Uint8Array(ab);
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        };

        // write the ArrayBuffer to a blob, and you're done
        return new Blob([ab], {
            type: mimeString
        });
    }
}