整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Dom-to-image截图将html生成图片

Dom-to-image截图将html生成图片

OM to Image

dom-to-image是一个js库,可以将任意dom节点转换为矢量(SVG)或光栅(PNG或JPEG)图像。

安装

npm install dom-to-image -S

加载

/* in ES 6 */
import domtoimage from 'dom-to-image';
/* in ES 5 */
var domtoimage=require('dom-to-image');

用法

所有高阶函数都接受DOM节点和渲染选项options ,并返回promises。

  1. 获取PNG图像base64编码的data URL:
<div id="my-node"></div>
var node=document.getElementById('my-node');
// options 可不传
var options={}  
domtoimage.toPng(node, options)
    .then(function (dataUrl) {
        var img=new Image();
        img.src=dataUrl;
        document.body.appendChild(img);
    })
    .catch(function (error) {
        console.error('oops, something went wrong!', error);
    });
  1. 获取图像blob:
domtoimage.toBlob(document.getElementById('my-node'))
    .then(function (blob) { 
        console.log('blob', blob)
    });
  1. 获取JPEG图像base64编码的data URL并下载:
domtoimage.toJpeg(document.getElementById('my-node'), { quality: 0.95 })
    .then(function (dataUrl) {
        var link=document.createElement('a');
        link.download='my-image-name.jpeg';
        link.href=dataUrl;
        link.click();
});
  1. 获取SVGdata URL,但筛选出所有元素:
function filter (node) {
    return (node.tagName !=='i');
}
 
domtoimage.toSvg(document.getElementById('my-node'), {filter: filter})
    .then(function (dataUrl) {
        /* do something */
});
  1. 以uint8数组的形式获取原始像素数据,每4个数组元素表示一个像素的RGBA数据:
var node=document.getElementById('my-node');
 
domtoimage.toPixelData(node)
    .then(function (pixels) {
        for (var y=0; y < node.scrollHeight; ++y) {
          for (var x=0; x < node.scrollWidth; ++x) {
            pixelAtXYOffset=(4 * y * node.scrollHeight) + (4 * x);
            /* pixelAtXY is a Uint8Array[4] containing RGBA values of the pixel at (x, y) in the range 0..255 */
            pixelAtXY=pixels.slice(pixelAtXYOffset, pixelAtXYOffset + 4);
          }
        }
    });

options参数

Name

类型

Default

Description

filter

Function

——

以DOM节点为参数的函数。如果传递的节点应包含在输出中,则应返回true(排除节点意味着也排除其子节点)

bgcolor

String

——

背景色的字符串值,任何有效的CSS颜色值。

height

Number

——

渲染前应用于节点的高度(以像素为单位)。

width

Number

——

渲染前应用于节点的宽度(以像素为单位)。

style

Object

——

object对象,其属性在渲染之前要复制到节点的样式中。

quality

Number

1.0

介于0和1之间的数字,表示JPEG图像的图像质量(例如0.92=>92%)。默认值为1.0(100%)

cacheBust

Boolean

false

设置为true可将当前时间作为查询字符串附加到URL请求以启用清除缓存。

imagePlaceholder

Boolean

undefined

获取图片失败时使用图片的数据URL作为占位符。默认为未定义,并将在失败的图像上引发错误。

原理

dom-to-image使用SVG的一个特性,它允许在标记中包含任意HTML内容。

  • 递归地克隆原始DOM节点
  • 计算节点和每个子节点的样式,并将其复制到相应的克隆 创建伪元素,因为它们不是以任何方式克隆的
  • 嵌入web字体 查找所有@font face声明的web字体 解析文件URL,下载相应文件 base64编码的内联作为data:URLs 将所有已处理的CSS放入中,然后将其附加到克隆
  • 嵌入图片 在嵌入图片URL 使用backgroundCSS属性的图片,方法类似于字体
  • 将克隆的节点序列化为XML
  • 将XML包装到标记中,然后包装到SVG中,然后使其成为data URL
  • 或者,要以Uint8Array的形式获取PNG内容或原始像素数据,可以创建一个以SVG为源的图像元素,并将其呈现在已经创建的canvas上,从canvas读取内容

部分源码分析

dom-to-image.js

// Default impl options
var defaultOptions={
    // Default is to fail on error, no placeholder
    imagePlaceholder: undefined,
    // Default cache bust is false, it will use the cache
    cacheBust: false
};

var domtoimage={
    toSvg: toSvg,
    toPng: toPng,
    toJpeg: toJpeg,
    toBlob: toBlob,
    toPixelData: toPixelData,
    impl: {
        fontFaces: fontFaces,
        images: images,
        util: util,
        inliner: inliner,
        options: {}
    }
};

if (typeof module !=='undefined')
    module.exports=domtoimage;
else
    global.domtoimage=domtoimage;
  • defaultOptions设置默认options选项
  • domtoimage的核心api:
    • toSvg
    • toPng
    • toJpeg
    • toBlob
    • toPixelData
  • 例:toJpeg:将draw函数返回的canvas实例,使用canvas的toDataURL方法生成jpeg图片。toSvg函数将递归地克隆原始DOM节点, 将克隆的节点序列化为XML,将XML包装到标记中,然后包装到SVG中,然后使其转成dataURL。
function toJpeg(node, options) {
   options=options || {};
   return draw(node, options)
       .then(function (canvas) {
           return canvas.toDataURL('image/jpeg', options.quality || 1.0);
       });
}
复制代码
function draw(domNode, options) {
    return toSvg(domNode, options)
        .then(util.makeImage)
        .then(util.delay(100))
        .then(function (image) {
            var canvas=newCanvas(domNode);
            canvas.getContext('2d').drawImage(image, 0, 0);
            return canvas;
        });

    function newCanvas(domNode) {
        var canvas=document.createElement('canvas');
        canvas.width=options.width || util.width(domNode);
        canvas.height=options.height || util.height(domNode);

        if (options.bgcolor) {
            var ctx=canvas.getContext('2d');
            ctx.fillStyle=options.bgcolor;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
        }

        return canvas;
    }
}
function toSvg(node, options) {
    options=options || {};
    copyOptions(options);
    return Promise.resolve(node)
        .then(function (node) {
            return cloneNode(node, options.filter, true);
        })
        .then(embedFonts)
        .then(inlineImages)
        .then(applyOptions)
        .then(function (clone) {
            return makeSvgDataUri(clone,
                options.width || util.width(node),
                options.height || util.height(node)
            );
        });

    function applyOptions(clone) {
        if (options.bgcolor) clone.style.backgroundColor=options.bgcolor;

        if (options.width) clone.style.width=options.width + 'px';
        if (options.height) clone.style.height=options.height + 'px';

        if (options.style)
            Object.keys(options.style).forEach(function (property) {
                clone.style[property]=options.style[property];
            });

        return clone;
    }
}


作者:知其
https://juejin.cn/post/6988045156473634852

家好,我是开源探索者,持续分享开源项目,关注技术的最新动态,分享自己的经验和见解。

大家好,我是开源探索者。

今天给大家介绍一个非常牛的开源项目:Screenshot-to-code

Screenshot-to-code 是一个可以将屏幕截图转化为 HTML/JS/Tailwind CSS 代码的工具。它利用 GPT-4 Vision 生成代码,结合 DALL-E 3 生成相似的图片。

项目特性

1、屏幕截图即代码

能够将屏幕截图瞬间转变为可运行的代码。这意味着,你只需要截取一个网页或应用程序的截图,Screenshot-to-code 就可以自动生成对应的 HTML、CSS、JavaScript 代码。

这项功能对于初学者来说非常友好,可以帮助快速学习前端开发。对于经验丰富的开发人员来说,也可以节省大量的时间和精力。

2、GPT-4 Vision

项目利用最新的 GPT-4 Vision 技术,可以生成高度智能化的代码,能够帮助我们更好地理解屏幕截图中的元素,并生成更加贴近设计意图的代码。

3、DALL-E 3 图片生成

可以结合 DALL-E 3 技术生成相似的图片,我们可以使用 Screenshot-to-code 生成一个网页或应用程序的截图,然后使用 DALL-E 3 生成一个相似的图片。

这项功能可以让我们的页面呈现更加丰富多彩、独具特色。

一个例子

如何快速使用

Screenshot-to-code 的使用很简单,官方给了很详细的说明。

使用前提是有一个能够访问 GPT-4 Vision API 的 OpenAI API 密钥。

接着按照下面的步骤:

1、下载 Screenshot-to-code 的源代码。

2、在 backend/.env 文件中添加你的 OpenAI API 密钥。

3、使用 poetry install 安装依赖项。

4、使用 poetry run uvicorn main:app --reload --port 700运行后端。(如果您希望在不同端口上运行后端,可以修改文件 VITE_WS_BACKEND_URLfrontend/.env.local)

5、使用 yarn 安装前端依赖项。

6、使用 yarn dev 运行前端。

7、打开浏览器,访问 http://localhost:5173 即可使用。

如果你安装了Docker,也可以用下面的命令快速开始:

echo "OPENAI_API_KEY=sk-your-key" > .env
docker-compose up -d --build

当然,如果你也不想这么麻烦,官方提供了一个在线的版本供体验使用

https://screenshottocode.com

目前 Screenshot-to-code 项目依然还在开发更新中,已经取得了令人印象深刻的进展。未来,Screenshot-to-code 会在支持更多的语言和框架、提高生成代码的准确性和效率、增加更多功能,例如代码片段共享和代码编辑器集成等方面进行提示。

开源君有一种感觉,Screenshot-to-code 有可能会成为未来前端开发的必备工具。

关于项目的更多细节,感兴趣的同学可以自行去项目地址查看。

项目地址:
https://github.com/abi/screenshot-to-code

结束语

在数字时代的浪潮中,有一群人他们不畏艰难,勇攀技术高峰,他们就是开源探索者。他们不仅仅是技术的实践者,更是开源文化的传播者和推动者。

在开源的世界里,没有绝对的权威,只有共同的合作。

文转自测试人社区,原文链接:selenium ---- 异常自动截图 - 学习笔记 - 测试人社区

# 目标1:实现代码异常的时候,截图/打印page_source
# 实现方法:try/catch 配合截图/ page_source操作
import time

import allure
from selenium import webdriver
from selenium.webdriver.common.by import By


#====问题1:异常处理会影响用例本身的结果(本该执行失败的用例,由于捕获了异常,导致执行成功)
# 解决方案: 在exception之后再把异常抛出(raise Exception)
#====问题2:异常捕获处理代码和业务代码无关,不能耦合
# 解决方案:使用装饰器装饰用例或者相关方法封装异常捕获处理代码
# 1、先把装饰器的架子搭好
# 2、把相关逻辑嵌套进来
#====问题3: 被装饰的函数test_baidu()还没执行, 就先调用了装饰器ui_exception_record,此时还没有self.driver,导致args[0]还获取不到self
# 解决方案:获取self.driver的操作,放在装饰器中被装饰的函数之后

#====问题4:隐藏的小bug,一旦被装饰方法有返回值,会丢失返回值
# 解决方案:给被装饰器装饰的方法添加return返回值
def ui_exception_record(func):
    def inner(*args, **kwargs):
        """
        内函数,实现封装异常捕获处理的代码
        :param args: 不定长参数,是个元组,args[0] 是 TestBaidu类的实例对象,相当于self
        :param kwargs:
        :return:
        """
        # 获取TestBaidu类中被装饰方法的self,也就是实例对象,args[0]相当于self,args[0].driver=self.driver
        # 前提条件: TestBaidu类中的driver变量是一个实例变量 self.driver
        try:
            # 当被装饰方法/函数发生异常,就捕获并做数据记录
            func(*args, **kwargs)
        except Exception:
            #====问题3: 被装饰的函数test_baidu()还没执行, 就先调用了装饰器ui_exception_record,此时还没有self.driver,导致args[0]还获取不到self
            # 解决方案一:获取self.driver的操作,放在装饰器中被装饰的函数func(*args, **kwargs)之后
            driver=args[0].driver
            # 出现异常情况
            # print("出现异常情况")
            # 截图操作
            timestamp=int(time.time())
            image_path=f"../images/image_{timestamp}.PNG"
            driver.save_screenshot(image_path)

            # page_source操作
            page_source_path=f"../page_source/page_source_{timestamp}.HTML"
            with open(page_source_path, "w", encoding="utf8") as f:
                f.write(driver.page_source)

            # 将截图放到allure报告中
            allure.attach.file(image_path, name="picture", attachment_type=allure.attachment_type.PNG)
            # 将page_source放到allure报告中
            # 如果想要HTML格式展示在报告中,则使用HTML
            allure.attach.file(page_source_path, name="page_source", attachment_type=allure.attachment_type.HTML)
            # 如果想要TEXT格式展示在报告中,则使用TEXT
            allure.attach.file(page_source_path, name="page_source", attachment_type=allure.attachment_type.HTML)

        # 待截图和page_source数据保存完成后,抛出异常,此时用例会按正常情况,执行失败
        raise Exception

    # 返回内函数对象
    return inner


class TestBaidu:
    def setup_class(self):
        # 解决方案二:在前置条件中对self.driver进行实例化操作
        self.driver=webdriver.Chrome()

    @ui_exception_record
    def find(self):
        return self.driver.find_element(By.ID, "su1")

    def test_baidu(self):
        self.driver.get("https://www.baidu.com")
        self.find().click()
        # self.driver.find_element(By.ID, "su1")

软件测试开发免费视频教程分享 - 公众号 - 测试人社区