Save page as image and optimizing HD screenshots | canvas picture cross-domain configuration

An important feature of this demand comes from the H5 technology research project: to achieve 微信长按网页保存为截图.

Here is a chestnut (Open with a micro-channel, long press on the image to save): 3 minutes to explore the boundaries of your knowledge

Save the whole web page as a picture is a very interesting feature, common in active page H5 end of a page to share. The following is a summary of some of the research projects and stepped pit and summary.


First, realize save the HTML page as image

1.1 Known viable options

Existing known to achieve save the page as a picture of the program include:

  • Scenario 1 : The DOM rewritten as canvas, and then use the canvas toDataURL way to achieve the output DOM containing picture showsdata URI
  • Scenario 2 : Using html2canvas.jsachieve (with optional Canvas2Image.jsrealized save the page as a picture)
  • Scenario 3 : Using rasterizeHTML.jsachieve

Select 1.2 solutions

  • Scheme 1 : DOM manual calculations for each element Computed Style, and element attributes need to calculate the size of the canvas and the like in position.

    方案1难点

    1. Equivalent to completely rewrite the entire page layout styles, increasing the workload.
    2. Because the canvas is no object concept, elements for rich, complex page layout, easy to reconstruction
    3. All rewrite the DOM element into the canvas will be some difficulties, such as: difficult to support a responsive, poor clarity of picture elements and text recognition problems hit area.
  • Scenario 2 : This class function on Github stars at most (still maintained), Stack Overflow also rich discussion. Simply call html2canvas method and set the configuration items.
  • Option 3 : limit the program's more, currently only supports three types of target format can be converted to canvas: page url, html string and document objects.

小结: Html2canvas is realized to save the page as a picture of the feature combining best choice.

1.3 html2canvas to use

官方GitHub:https://github.com/niklasvh/h...

The following description is for html2canvas version0.5.0-beta4

1.3.1 The first step to achieve saved as a picture: html into canvas

Based on html2canvas.jsone element can be rendered as canvas, simply call html2canvas(element[, options]);can be. The following html2canvasmethod returns a containing <canvas>elements promise:

html2canvas(document.body).then(function(canvas) {
    document.body.appendChild(canvas);
});

1.3.2 The second step to achieve saved as a picture: canvas transfer image

Previous resulting canvas is the target element contains <canvas>an element object. Achievement of objectives only need to save the image canvas transfer image can be.

Here's conversion program has 2种:

  • Scheme 1 : Native canvas based toDataURLmethod canvas output data: URItype image address, then the address is assigned to the image <image>src attribute element to

MDN: toDataURL () API Detailed

  • Scenario 2 : Using third-party libraries Canvas2Image.js, call its convertToImagemethods can be ( GitHub )

In fact, Canvas2Image.jsalso based on canvas.toDataURLthe package, compared to the native canvas API into the picture for the function to consider more specific (uncompressed package size is 7.4KB), suitable for project use.

Second, to achieve optimization of HD screenshots

2.1 basis of clear shots optimization

The final picture clarity 取决于the first step in converting into html canvas clarity.

Existing solutions by reference;

Its basic principle is:
the canvasattributes widthand heightattribute enlarged 2 times (or setting devicePixelRatiotimes), and finally the canvas width and height of the CSS style is set to 1 times the original size.

For example : html desirable actually displayed in <canvas>width and height, respectively 160px, 90pxcan be set up as follows

<canvas width="320" height="180" style="width:160px;height:90px;"></canvas>

Particular reference to the above documents use case are as follows;

convert2canvas() {

    var shareContent = YourTargetElem; 
    var width = shareContent.offsetWidth; 
    var height = shareContent.offsetHeight; 
    var canvas = document.createElement("canvas"); 
    var scale = 2; 

    canvas.width = width * scale; 
    canvas.height = height * scale; 
    canvas.getContext("2d").scale(scale, scale); 

    var opts = {
        scale: scale, 
        canvas: canvas, 
        logging: true, 
        width: width, 
        height: height 
    };
    html2canvas(shareContent, opts).then(function (canvas) {
        var context = canvas.getContext('2d');

        var img = Canvas2Image.convertToImage(canvas, canvas.width, canvas.height);

        document.body.appendChild(img);
        $(img).css({
            "width": canvas.width / 2 + "px",
            "height": canvas.height / 2 + "px",
        })
    });
}

Screenshot clear advanced optimization 2.2

These settings can usually solve the problem screenshots effect is not clear, but exploration is far from over.

The actual in our project, even if made 2.1节after the set, fuzzy rendering results into large fruit is still to clear fantasy hit zero.

Below given directly to three further optimization strategy:

  1. Change 百分比布局to px布局(if the original layout is the percentage of words)
  2. 关闭canvas default 抗锯齿设setting
  3. Fuzzy set of elements widthand heightas the material of the original width and height, and then by transform: scalescaling. Here scalethe value is determined by the specific needs.

Fundamental

  1. If the original use of the percentage of the element's width and height, change to px为单位the width and height, to avoid blur caused styles secondary computing
  2. By default, canvas anti-aliasing is turned on, the need 关闭抗锯齿to achieve sharpen the image of ( the MDN: imageSmoothingEnabled )
  3. In addition canvas can be increased by enlarging the resolution twice the width and height is then scaled to the original width and height, the DOM for other elements may be used css样式to scaleachieve the same scaling

Example: html2canvas Configuration

convert2canvas() {

    var cntElem = $('#j-sec-end')[0];

    var shareContent = cntElem;//需要截图的包裹的(原生的)DOM 对象
    var width = shareContent.offsetWidth; //获取dom 宽度
    var height = shareContent.offsetHeight; //获取dom 高度
    var canvas = document.createElement("canvas"); //创建一个canvas节点
    var scale = 2; //定义任意放大倍数 支持小数
    canvas.width = width * scale; //定义canvas 宽度 * 缩放
    canvas.height = height * scale; //定义canvas高度 *缩放
    canvas.getContext("2d").scale(scale, scale); //获取context,设置scale 
    var opts = {
        scale: scale, // 添加的scale 参数
        canvas: canvas, //自定义 canvas
        // logging: true, //日志开关,便于查看html2canvas的内部执行流程
        width: width, //dom 原始宽度
        height: height,
        useCORS: true
    };

    html2canvas(shareContent, opts).then(function (canvas) {

        var context = canvas.getContext('2d');
        context.mozImageSmoothingEnabled = false;
        context.webkitImageSmoothingEnabled = false;
        context.msImageSmoothingEnabled = false;
        context.imageSmoothingEnabled = false;

        var img = Canvas2Image.convertToJPEG(canvas, canvas.width, canvas.height);

        document.body.appendChild(img);

        $(img).css({
            "width": canvas.width / 2 + "px",
            "height": canvas.height / 2 + "px",
            // 'border': '10px solid #000'
        }).addClass('f-full');

        $('#j-sec-end').remove();
    });
}

Example: DOM element style:

.targetElem {width: 54px;height: 142px;margin-top:2px;margin-left:17px;transform: scale(0.5)}

<! - ## 2.3 Comparative optimization results
(mac the screenshot can be compared) ->

Third, the cross-domain configuration contains pictures

As the canvas for a picture of resources 同源限制, picture resources if the canvas contains cross-domain will pollute the canvas, causing confusion generated picture style or method does html2canvas and other issues.

Mainly to solve the following picture of cross-domain resource categories include: CORS has been configured through the CDNimages and resources in the 微信用户头像picture resources.

3.1 For a picture of the CDN configuration

  1. CDN configuration requirements of a good picture CORS. CDNOnce configured, can be seen by the response header should contain chrome developer tools Access-Control-Allow-Originfields.
  2. Open html2canvasthe useCORSconfiguration items . That is set up as follows:

    useCORS: true
}
html2canvas(element, options);

注意:
If you do not open html2canvasthe useCORSconfiguration items, html2canvasexecutes properly and does not complain, but will not output the corresponding CDN picture
(ie on the same page, can be tested simultaneously contain CDN的图片and 本地图片page resources, but only 本地图片to be properly rendered)

3.2 micro-channel configuration for user avatar

If you need a 微信platform user avatar kept together as a picture, 3.1the program can do. Can be configured 代理转发to achieve, not be repeated here.

Other Considerations

Occlusion (1) margin of

Micro-channel, the call up 长按保存图片the menu requires the object is directly press <image>element, if <image>present above the shutter element will not call up the menu.
In fact, not just non-blocking caused <image>elements may also be a marginproperty. For example: if the bottom of the page, the elements of an absolute positioning set value greatly margin-top, the margin-toparea in question, were unable to call up the menu press. Solution: margin-topuse as topcan be.

(2) Andrews version micro letter failed to save the image problem

canvas2imgThe default format to save the image png, and in the Andrews version micro letter can be generated pictures Despite press evocative menu to save the image, but can not be saved correctly to a local album . 解决方案: Set canvas2imggeneration picture format for configuration items jpegcan be.

(3) JPEG black screen problem

Set the canvas2imgoutput format jpeg, there is a chance to cause the resulting image contains a large amount of a black block. 可能的解决方案: Reducing the size of the picture element size and the volume of the background image.

(4) dynamic efficiency can not be retained

In the picture 转化前, you must 停止post or delete dynamic efficiency in order to correctly render the picture, otherwise the resulting picture is broken.

references

Guess you like

Origin www.cnblogs.com/homehtml/p/12207860.html