2014-10-07 156 views
2

有没有一种简单的方法可以从url中获取图像并放入PDFKit pdf?在浏览器中使用PDFkit,从链接中插入图片

我有一个PDF在浏览器中自动生成。有一个我想要的图像,我有一个URL。问题在于我在浏览器中生成PDF。由于我从互联网上获得URL,所以似乎应该有一种简单的方法将该图像转换为PDFKit可读的内容。

有没有一种方法可以将JavaScript图像URL转换为PDFKit可读的缓冲区?

我要的是你想什么,下面的命令做的事:提前

doc.image('http://upload.wikimedia.org/wikipedia/commons/0/0c/Cow_female_black_white.jpg') 

感谢。我在网上找到的解决方案让您的服务器接入链路,并用缓冲区进行响应。这是唯一的方法吗?或者有没有一种方法在浏览器中没有http发布?

+0

您从中提取图像的服务器可能需要是您的(相同来源)或需要使用适当的CORS标头进行响应。 Wikimedia.org确实如此,但大多数服务器不会。如果你需要使用任意的URL,那么你的服务器将不得不代理图像。 – josh3736 2014-10-07 17:28:05

+0

这是我的服务器。那么在那种情况下,有一个简单的方法可以做到吗? – 2014-10-07 17:38:08

回答

3

我找回通过AJAX的图像作为base64编码字符串,然后用下面的代码base64编码字符串转换成可用的缓冲区:

var data = atob(base64); 
    var buffer = []; 
    for (var i = 0; i < data.length; ++i) 
     buffer.push(data.charCodeAt(i)); 
    buffer._isBuffer = true; 
    buffer.readUInt16BE = function(offset, noAssert) { 
     var len = this.length; 
     if (offset >= len) return; 

     var val = this[offset] << 8; 
     if (offset + 1 < len) 
      val |= this[offset + 1]; 
     return val; 
    }; 

    pdf.image(buffer); 

又见https://github.com/devongovett/pdfkit/issues/354#issuecomment-68666894,其中相同的问题被讨论为适用于字体。

0

这是一个很老的问题,但我会添加我的笔记,因为这是在Google上查找“pdfkit浏览器图像”时的第一个建议。

我根据我的数据URI选项supported by PDFKit解决方案:

只是传递的图像路径,缓冲区,或数据URI用base64编码数据 到图像的方法与一些可选参数一起。

因此,经过快速浏览后,我发现从图像URL获取数据URI的一般方法是使用画布,like in this post。把他们放在一起PDFKit's interactive browser demo

function getDataUri(url, callback) { 
    var image = new Image(); 

    image.crossOrigin = 'anonymous' 
    image.onload = function() { 
    var canvas = document.createElement('canvas'); 
    canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size 
    canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size 

    canvas.getContext('2d').drawImage(this, 0, 0); 

    // // Get raw image data 
    // callback(canvas.toDataURL('image/png').replace(/^data:image\/(png|jpg);base64,/, '')); 

    // ... or get as Data URI 
    callback(canvas.toDataURL('image/png')); 
    }; 

    image.src = url; 
} 

// Usage 
getDataUri('http://pdfkit.org/docs/img/14.png', function(dataUri) { 
    // create a document and pipe to a blob 
    var doc = new PDFDocument(); 
    var stream = doc.pipe(blobStream()); 

    doc.image(dataUri, 150, 200, { 
    width: 300 
    }); 

    // end and display the document in the iframe to the right 
    doc.end(); 
    stream.on('finish', function() { 
    iframe.src = stream.toBlobURL('application/pdf'); 
    }); 
}); 
0

我会权衡在这个问题上我的2美分,我只是花了很多时间一个很好的协议得到它的工作。这是我发现用Google搜索这个问题的一系列答案。

var doc = new PDFDocument(); 
var stream = doc.pipe(blobStream()); 

var files = { 
img1: { 
    url: 'http://upload.wikimedia.org/wikipedia/commons/0/0c/Cow_female_black_white.jpg', 
    } 
}; 

在一个地方使用上述对象来存储PDF中需要的所有图像和其他文件。

var filesLoaded = 0; 

//helper function to get 'files' object with base64 data 
function loadedFile(xhr) { 
    for (var file in files) { 
    if (files[file].url === xhr.responseURL) { 
     var unit8 = new Uint8Array(xhr.response); 
     var raw = String.fromCharCode.apply(null,unit8); 
     var b64=btoa(raw); 
     var dataURI="data:image/jpeg;base64,"+b64; 
     files[file].data = dataURI; 
    } 
} 
filesLoaded += 1; 

//Only create pdf after all files have been loaded 
if (filesLoaded == Object.keys(files).length) { 
    showPDF(); 
    } 
} 

//Initiate xhr requests 
for (var file in files) { 
    files[file].xhr = new XMLHttpRequest(); 
    files[file].xhr.onreadystatechange = function() { 
    if (this.readyState == 4 && this.status == 200) { 
     loadedFile(this); 
    }  
    }; 

    files[file].xhr.responseType = 'arraybuffer'; 
    files[file].xhr.open('GET', files[file].url); 
    files[file].xhr.send(null); 
} 

function showPDF() { 
    doc.image(files.img1.data, 100, 200, {fit: [80, 80]}); 
    doc.end() 
} 

//IFFE that will download pdf on load 
var saveData = (function() { 
    var a = document.createElement("a"); 
    document.body.appendChild(a); 
    a.style = "display: none"; 
    return function (blob, fileName) { 
    var url = window.URL.createObjectURL(blob); 
    a.href = url; 
    a.download = fileName; 
    a.click(); 
    window.URL.revokeObjectURL(url); 
    }; 
}()); 

stream.on('finish', function() { 
    var blob = stream.toBlob('application/pdf'); 
    saveData(blob, 'aa.pdf'); 
}); 

我碰到渐渐从arraybuffer类型使用Base64数据串的信息的最大的问题。我希望这有帮助!

这里是js fiddle其中大部分xhr代码来自。