如何使用外部图像生成 "screenshot" of html div?
How to generate "screenshot" of html div with external images?
我有一个带有外部图像的 HTML div。 (以下是一个示例,但在实际情况下我使用的是 Amazon S3,因此无法将图像下载并存储在同一台服务器上)目前我正在使用 html2canvas 转换 div印象。但是,外部图像总是被空白替换 space.
我用来抓图的代码:
$(function() {
$("#btnSave").click(function() {
html2canvas($("#widget"), {
onrendered: function(canvas) {
theCanvas = canvas;
document.body.appendChild(canvas);
// Convert and download as image
Canvas2Image.saveAsPNG(canvas);
$("#img-out").append(canvas);
}
});
});
});
编辑: jsfiddle:https://jsfiddle.net/0y2zxxL8/3/
我可能会使用其他图书馆。我也可以在后端这样做。 (我正在使用 PHP + laravel 5 作为后端)有没有办法用外部图像生成 HTML div 的 "screenshot"?
更新 当前答案在编辑后有效。然而,对于我的实际使用,将有多个图像,其位置由用户通过拖放设置。我还是可以拿到位置的,但是如果可以不专门设置位置的话对我来说会更好
你的 JSFiddle 在点击 'Save PNG' 按钮时得到 ReferenceError: Canvas2Image is not defined
。所以检查你的代码(不是 fiddle)是否有同样的错误。
更新
请参阅此 JSFiddle 示例作为参考。希望这篇文章能帮到你。
更新 2
我将一些代码放入您的代码中,请检查一下。希望这将是您的解决方案..!
FF v44 的工作结果及其工作。使用 JSFiddle 代码拍摄
$(function() {
$("#btnSave").click(function() {
html2canvas($("#widget"), {
onrendered: function(canvas) {
var context=canvas.getContext("2d"); // returns the 2d context object
var img=new Image() //creates a variable for a new image
img.src= "http://lorempixel.com/400/200/"; // specifies the location of the image
context.drawImage(img,0,50); // draws the image at the specified x and y location
// Convert and download as image
theCanvas = canvas;
document.body.appendChild(canvas);
// Convert and download as image
Canvas2Image.saveAsPNG(canvas);
$("#img-out").append(canvas);
}
});
});
});
更新 3 (12/29/2016) JSFiddle
经过研究,发现问题是因为我们只分配了图像源,它只是传递消息给浏览器来检索数据。
当单击从中绘制 canvas 时,浏览器可能无法真正访问其他图像元素。我们只是告诉代码加载它,它就完成了。
更改代码以解决 OP 面临的 chrome 问题,如下所示:
img.onload = function() {
context.drawImage(img, 0, 50);// draws the image at the specified x and y location
}
更新 4 JSFiddle
根据OP要求使图像位置动态化。
您可以尝试扫描图像源以获取外部 url,并将其更改为您的网站并使用 php 加载它们。
类似
$(function() {
var imageproxy = "http://example.com/imageproxy.php"; //Change this
var mydomain = new RegExp(location.host);
$("#btnSave").click(function() {
$("#widget").find('img').each(function(){
var img_src = $(this).attr('src');
if(!mydomain.test(img_src)){
$(this).attr('src', imageproxy + "?url=" + encodeURIComponent(img_src));
}
});
html2canvas($("#widget"), {
onrendered: function(canvas) {
var link = $('<a target="_blank">Download</a>');
link.attr('download', 'test.png');
link.attr('href', canvas.toDataURL());
$("#btnSave").after(link);
}
});
});
});
imageproxy.php
<?php
if(!empty($_GET['url'])){
$url = urldecode($_GET['url']);
$img_type = "image/jpeg";
$chunks = explode('.', $url);
if(is_array($chunks) && count($chunks) > 1){
$ext = end($chunks);
switch ($ext){
case 'jpg':
case 'jpeg':
$img_type = "image/jpeg";
break;
case 'png':
$img_type = "image/png";
break;
case 'gif':
$img_type = "image/gif";
break;
}
}
$img = file_get_contents($url);
header ("Content-Type: $img_type");
echo $img;
}
注意:php脚本非常简单,图像检测并非 100% 有效,这只是给您一个想法。如果您使用一些 php 图像库来加载和获取图像类型,您只需几行代码即可完成此操作。你也可以尝试 "php readfile".
onrendered 不再工作..
我通过添加 "allowTaint" 选项解决了这个问题
{ allowTaint: true }
2018 解决方案:
html2canvas(document.getElementById('result'), { allowTaint: true }).then(function (canvas) {
document.body.appendChild(canvas);
});
我有一个带有外部图像的 HTML div。 (以下是一个示例,但在实际情况下我使用的是 Amazon S3,因此无法将图像下载并存储在同一台服务器上)目前我正在使用 html2canvas 转换 div印象。但是,外部图像总是被空白替换 space.
我用来抓图的代码:
$(function() {
$("#btnSave").click(function() {
html2canvas($("#widget"), {
onrendered: function(canvas) {
theCanvas = canvas;
document.body.appendChild(canvas);
// Convert and download as image
Canvas2Image.saveAsPNG(canvas);
$("#img-out").append(canvas);
}
});
});
});
编辑: jsfiddle:https://jsfiddle.net/0y2zxxL8/3/
我可能会使用其他图书馆。我也可以在后端这样做。 (我正在使用 PHP + laravel 5 作为后端)有没有办法用外部图像生成 HTML div 的 "screenshot"?
更新 当前答案在编辑后有效。然而,对于我的实际使用,将有多个图像,其位置由用户通过拖放设置。我还是可以拿到位置的,但是如果可以不专门设置位置的话对我来说会更好
你的 JSFiddle 在点击 'Save PNG' 按钮时得到 ReferenceError: Canvas2Image is not defined
。所以检查你的代码(不是 fiddle)是否有同样的错误。
更新
请参阅此 JSFiddle 示例作为参考。希望这篇文章能帮到你。
更新 2
我将一些代码放入您的代码中,请检查一下。希望这将是您的解决方案..!
FF v44 的工作结果及其工作。使用 JSFiddle 代码拍摄
$(function() {
$("#btnSave").click(function() {
html2canvas($("#widget"), {
onrendered: function(canvas) {
var context=canvas.getContext("2d"); // returns the 2d context object
var img=new Image() //creates a variable for a new image
img.src= "http://lorempixel.com/400/200/"; // specifies the location of the image
context.drawImage(img,0,50); // draws the image at the specified x and y location
// Convert and download as image
theCanvas = canvas;
document.body.appendChild(canvas);
// Convert and download as image
Canvas2Image.saveAsPNG(canvas);
$("#img-out").append(canvas);
}
});
});
});
更新 3 (12/29/2016) JSFiddle
经过研究,发现问题是因为我们只分配了图像源,它只是传递消息给浏览器来检索数据。
当单击从中绘制 canvas 时,浏览器可能无法真正访问其他图像元素。我们只是告诉代码加载它,它就完成了。
更改代码以解决 OP 面临的 chrome 问题,如下所示:
img.onload = function() {
context.drawImage(img, 0, 50);// draws the image at the specified x and y location
}
更新 4 JSFiddle
根据OP要求使图像位置动态化。
您可以尝试扫描图像源以获取外部 url,并将其更改为您的网站并使用 php 加载它们。
类似
$(function() {
var imageproxy = "http://example.com/imageproxy.php"; //Change this
var mydomain = new RegExp(location.host);
$("#btnSave").click(function() {
$("#widget").find('img').each(function(){
var img_src = $(this).attr('src');
if(!mydomain.test(img_src)){
$(this).attr('src', imageproxy + "?url=" + encodeURIComponent(img_src));
}
});
html2canvas($("#widget"), {
onrendered: function(canvas) {
var link = $('<a target="_blank">Download</a>');
link.attr('download', 'test.png');
link.attr('href', canvas.toDataURL());
$("#btnSave").after(link);
}
});
});
});
imageproxy.php
<?php
if(!empty($_GET['url'])){
$url = urldecode($_GET['url']);
$img_type = "image/jpeg";
$chunks = explode('.', $url);
if(is_array($chunks) && count($chunks) > 1){
$ext = end($chunks);
switch ($ext){
case 'jpg':
case 'jpeg':
$img_type = "image/jpeg";
break;
case 'png':
$img_type = "image/png";
break;
case 'gif':
$img_type = "image/gif";
break;
}
}
$img = file_get_contents($url);
header ("Content-Type: $img_type");
echo $img;
}
注意:php脚本非常简单,图像检测并非 100% 有效,这只是给您一个想法。如果您使用一些 php 图像库来加载和获取图像类型,您只需几行代码即可完成此操作。你也可以尝试 "php readfile".
onrendered 不再工作..
我通过添加 "allowTaint" 选项解决了这个问题
{ allowTaint: true }
2018 解决方案:
html2canvas(document.getElementById('result'), { allowTaint: true }).then(function (canvas) {
document.body.appendChild(canvas);
});