javascript - 如何在不变形的情况下将 Canvas 传递给pdf

标签 javascript

我正在使用 react 和 openlayers,它们是不同类型(矢量、wms 等) map 的框架。我遇到的问题是,使用我的代码捕获 Canvas 并将其传递给 pdf(通过库 jsPDF),pdf 中显示的图像显示变形、拉伸(stretch)……也就是说,未保持相同的尺寸和比例。

例如,我在生成 pdf 之前放置了几个日志来捕获 Canvas 的宽度和高度,我得到了这些结果:宽度:3076 像素和高度:1672 像素,我选择了尺寸为 21.0 厘米的 A4和 29.7 厘米。

我一直在查看有关如何调整 Canvas 元素大小以使其不变形的示例,但我做不到。如何在不成比例的情况下缩放图像?我必须牢记什么:像素和其他里程碑是一回事吗?屏幕的像素密度?

这是我的代码,如果你能帮助我解决我的问题,我将不胜感激,因为它让我发疯。

downloadImage = () => {

    var dims = {
        a0: [1189, 841],
        a1: [841, 594],
        a2: [594, 420],
        a3: [420, 297],
        a4: [297, 210],
        a5: [210, 148]
    };

    var format = this.state.format;
    var dim = dims[format];
    var canvas = document.getElementsByTagName("canvas")[0];
    var imgData = canvas.toDataURL("image/jpeg", 1.0);
    var pdf;
    if (this.state.orientation === 'portrait') {
        pdf = new jsPDF('portrait', undefined, format);
        pdf.addImage(imgData, 'JPEG', 0, 0, dim[1], dim[0]);
    } else {        
        pdf = new jsPDF('landscape', undefined, format);
        pdf.addImage(imgData, 'JPEG', 0, 0, dim[0], dim[1]);
    }

    pdf.save(`map-${format}-${this.state.orientation}.pdf`);
}

CSS
-----
.map {
   position: absolute;
   width: 100%;
   height: 100%;
}

最佳答案

我很简单。假设您想要将图像放在页面边界内而不剪裁它的任何部分,您有 3 种情况:

  1. 缩放后,图像的宽度恰好适合页面宽度,并且在垂直方向上留有额外的空白。在这种情况下,您需要以 page.width/image.width 的比例缩放图像。 .如何知道是否是这种情况?当image.width/image.height > page.width/page.height

  2. 缩放后,图像的高度恰好适合页面边界,并且水平尺寸中留有空白,当 image.width/image.height < page.width/page.height 时.现在您需要以 page.height/image.height 的比例缩放图像

  3. 图像在水平和垂直方向上都完全适合 (image.width/image.height == page.width/page.height)。这可以简化为前面的任何一种情况,因为您可以将两者的比率计算为 page.height/image.heightpage.width/image.width .

请记住,页面宽度和高度取决于页面方向,因此您需要将它们换成横向。因此,假设您已经获得 Canvas 尺寸并将其分配给 imageWidth 和 imageHeight:

...
//I don't like hoisting, so let's declare the variables here ;)
var pageWidth, pageHeight;

if (this.state.orientation === 'portrait') {
    pageWidth = dim[1];
    pageHeight = dim[0]
} else {        
    pageWidth = dim[0];
    pageHeight = dim[1]
}
var ratio = imageWidth/imageHeight >= pageWidth/pageHeight ? pageWidth/imageWidth : pageHeight/imageHeight;
pdf = new jsPDF(this.state.orientation, undefined, format);
pdf.addImage(imgData, 'JPEG', 0, 0, imageWidth * ratio, imageHeight * ratio);
...

这没有考虑任何边距,但我相信您可以在需要时处理它们。

关于javascript - 如何在不变形的情况下将 Canvas 传递给pdf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49969113/

相关文章:

javascript - 横向溢出滑动面板

javascript - 使用 Node.js 和 Express 创建 HTTPs 服务器

JavaScript 正则表达式评估

javascript - 如何: request the url and zip it with response in rxjs?

Javascript 将对象子对象合并到一个新对象

javascript - 如何在 HTML JavaScript 自定义文本格式化程序中实现减少缩进?

javascript - 如何让 javascript 打印一个 json 对象(从 ruby​​ 发送)而不将其解释为 html?

javascript - Angular 2+,下拉更改读取值和加载数据 - json 文件

javascript - 来自对象属性的html上的angularjs ng-class

javascript - D3 TreeMap - 使用直线而不是对 Angular 线时如何转换链接