如何使用JavaScript将图像/ HTML画布切成两半?

7
我正在使用html2canvas将具有自定义功能的Google地图JavaScript API转换为画布,然后转换为图像。在除IE 11以外的所有浏览器上都可以正常工作,但是在IE 11上生成的图像右侧会有额外的空白空间,等于(浏览器窗口宽度-地图宽度)。因此,我的窗口越宽,右侧的空间就越多,反之亦然。如何在实际图像边缘(768px宽)精确地切割此图像(或HTMLcanvas)?

IE11 image

我在这里找到了这段代码,但不知道如何修改它以适应此任务:
var image = new Image();
image.onload = cutImageUp;
image.src = 'myimage.png';

function cutImageUp() {
    var imagePieces = [];
    for(var x = 0; x < numColsToCut; ++x) {
        for(var y = 0; y < numRowsToCut; ++y) {
            var canvas = document.createElement('canvas');
            canvas.width = widthOfOnePiece;
            canvas.height = heightOfOnePiece;
            var context = canvas.getContext('2d');
            context.drawImage(image, x * widthOfOnePiece, y * heightOfOnePiece, widthOfOnePiece, heightOfOnePiece, 0, 0, canvas.width, canvas.height);
            imagePieces.push(canvas.toDataURL());
        }
    }

    // imagePieces now contains data urls of all the pieces of the image

    // load one piece onto the page
    var anImageElement = document.getElementById('myImageElementInTheDom');
    anImageElement.src = imagePieces[0];
}
3个回答

9
这是一个可创建图像的画布裁剪器,与地图相关,你需要调整裁剪尺寸。

// initialize the test canvas and wireup cut button.
(function() {
  var can = document.getElementById('test');
  var w = can.width = 400;
  var h = can.height = 200;
  var ctx = can.getContext('2d');

  ctx.fillStyle = "#336699";
  ctx.fillRect(0, 0, 200, 200);
  ctx.strokeStyle = "#000000";
  ctx.lineWidth = 20;
  ctx.strokeRect(0, 0, w, h);
  ctx.strokeRect(0, 0, w / 2, h);
  var btn = document.getElementById('cut');
  btn.addEventListener('click', function() {
     
    var croppedCan = crop(can, {x: 0, y: 0}, {x: 200, y: 200});
    
    // Create an image for the new canvas.
    var image = new Image();
    image.src = croppedCan.toDataURL();
  
    // Put the image where you need to.
    document.getElementsByTagName('body')[0].appendChild(image);
    return image;
    
  });
})();


// function crop
// Returns a cropped canvas given a cavnas and crop region.
//
// Inputs:
// can, canvas
// a, {x: number, y: number} - left top corner
// b, {x: number, y: number} - bottom right corner

function crop(can, a, b) {
    // get your canvas and a context for it
    var ctx = can.getContext('2d');
    
    // get the image data you want to keep.
    var imageData = ctx.getImageData(a.x, a.y, b.x, b.y);
  
    // create a new cavnas same as clipped size and a context
    var newCan = document.createElement('canvas');
    newCan.width = b.x - a.x;
    newCan.height = b.y - a.y;
    var newCtx = newCan.getContext('2d');
  
    // put the clipped image on the new canvas.
    newCtx.putImageData(imageData, 0, 0);
  
    return newCan;    
 }
<button id='cut'>Crop</button>
<hr/>
<canvas id='test'></canvas>
<hr/>


看起来很不错。我明天回到办公室后会测试一下并写一个更新。谢谢! - TetraDev
做得非常漂亮,完美运行。我会将我的完整代码添加到你的基础上。 - TetraDev
你能解释一下为什么我们需要在匿名函数内部使用 return image; 吗?这个语句具体是做什么的?我还在尝试理解立即调用的匿名函数内返回值的工作原理。 - TetraDev
据我所知,这并没有起到任何作用。可以将其删除,应该没问题。 - wolfhammer

1
这是我编写的代码,它获取谷歌地图,生成画布,在实际图像边缘进行切片以修复IE 11的错误,然后输出新图像,并最终打印容器。
    // Insert map container for output to printer 
    var element = $("#map-container");
    var printContainer = $("#printContainer");

    html2canvas(element, {
        useCORS: true,
        onrendered: function (canvas) {

            // Must clear the printContainer before each session prints, or it will also print the previous info (if user presses the print results button twice)
            printContainer.empty();

            // Put the map into a canvas inside #printContainer
            printContainer.append(canvas);

            // Find the canvas we just made
            var myCanvas = printContainer.find("canvas")[0]; // add the [0] to get the native DOM element object
            myCanvas.id = 'generatedCanvas1';

            // Check if we're running IE 11 or earlier
            var ua = window.navigator.userAgent;
            var isIE = (ua.indexOf('MSIE') > 0 || ua.indexOf('Trident') > 0);

            if (isIE) {
                console.log("We're on IE");

                // ==========================================================================================
                // ======= IE Fix for canvas / image generation - slice the canvas ==========================
                // ==========================================================================================


                // function crop
                // Returns a cropped canvas given a cavnas and crop region.
                //
                // Inputs:
                // can, canvas
                // a, {x: number, y: number} - left top corner
                // b, {x: number, y: number} - bottom right corner


                (function() {
                    var croppedCan = crop(myCanvas, { x: 0, y: 0 }, { x: 800, y: 768 });

                    // Create an image for the new canvas.
                    var image = new Image();
                    image.src = croppedCan.toDataURL();


                    // Should we print the map image? Only if this is true...
                    if ($('*').hasClass('map-invisible posrel map-show')) {

                        //var dataUrl = canvas.toDataURL("image/png");

                        imageMap = '<p style="text-align:center;"><img id="canvasImage" src="' + image.src + '"  height="800" width="768" /></p>';
                        div.append('<p>&nbsp;</p>').html();
                        div.append(imageMap);
                    }

                    // Put the image where you need to.
                    //document.getElementById('printContainer').appendChild(image);
                    return image;

                    //});
                })();


                function crop(can, a, b) {
                    // get your canvas and a context for it
                    var ctx = can.getContext('2d');

                    // get the image data you want to keep.
                    var imageData = ctx.getImageData(a.x, a.y, b.x, b.y);

                    // create a new cavnas same as clipped size and a context
                    var newCan = document.createElement('canvas');
                    newCan.width = b.x - a.x;
                    newCan.height = b.y - a.y;
                    var newCtx = newCan.getContext('2d');

                    // put the clipped image on the new canvas.
                    newCtx.putImageData(imageData, 0, 0);

                    return newCan;
                }


                // ==========================================================================================
                // ======= END IE Fix for canvas / image generation - slice the canvas ======================
                // ==========================================================================================
            } else {
               console.log("We're not on IE");
                // For all other browsers except IE

                // Should we print the map image? Only if this is true...
                if ($('*').hasClass('map-invisible posrel map-show')) {

                    var image = new Image();
                    image.src = canvas.toDataURL("image/png");

                    imageMap = '<p style="text-align:center;"><img id="canvasImage" src="' + image.src + '"  height="800" width="768" /></p>';
                    div.append('<p>&nbsp;</p>').html();
                    div.append(imageMap);
                }
            }


            // Build the data set
            div.append(criteriaDiv);
            div.append(pageTable).html();


            // Add the new data into the hidden printContainer
            printContainer.append(div);

            // Remove the original canvas which was cropped so it doesnt print with the new canvas image
            $("#generatedCanvas1").remove();

            // Fire the print command
            printContainer.printThis({
                //debug: true
                printDelay: 1500            // variable print delay needed so that css has time to load for the printout

            });


            // For Debugging with the "#printMe" button
            $(function () {
                $("#printMe").click(function () {
                    //$printIframe.printThis({
                    //    debug: true,
                    printDelay: 1500            // variable print delay

                    //});
                    var $iframe = $("iframe[name='printIframe']");


                    setTimeout(function () {
                        if ($iframe.hasClass("MSIE")) {
                            // check if the iframe was created with the ugly hack
                            // and perform another ugly hack out of neccessity
                            window.frames["printIframe"].focus();
                            $head.append("<script>  window.print(); </script>");
                        } else {
                            // proper method
                            if (document.queryCommandSupported("print")) {
                                $iframe[0].contentWindow.document.execCommand("print", false, null);
                            } else {
                                $iframe[0].contentWindow.focus();
                                $iframe[0].contentWindow.print();
                            }
                        }


                    }, 333);
                });
            });

            // PrintThis usage and options
            //*  $("#mySelector").printThis({
            //*      debug: false,               * show the iframe for debugging
            //*      importCSS: true,            * import page CSS
            //*      importStyle: false,         * import style tags
            //*      printContainer: true,       * grab outer container as well as the contents of the selector
            //*      loadCSS: "path/to/my.css",  * path to additional css file - us an array [] for multiple
            //*      pageTitle: "",              * add title to print page
            //*      removeInline: false,        * remove all inline styles from print elements
            //*      printDelay: 333,            * variable print delay
            //*      header: null,               * prefix to html
            //*      formValues: true            * preserve input/form values
            //*  });
        }
    });

0

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