我正在使用Sharp 库来创建动态JPEG 车牌图像。
基本上,我有一个 PNG,它是一个没有数字的虚荣车牌。然后我像这样在代码中创建一个svg
const svg = new Buffer(
`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="${x} ${y} 500 40">
<defs>
<style type="text/css">
<![CDATA[
@font-face {
font-family: LicensePlate;
src: url('LicensePlate.ttf');
}
svg {
width: 100%;
height: 100%;
}
]]>
</style>
</defs>
<text x="0" y="0" font-family="LicensePlate" font-size="${fontsize}" letter-spacing="${letterspace}">
${platenumber.toUpperCase()}
</text>
</svg>`
);
传入所需的宽度、高度和车牌号。然后我使用sharp库将我的SVG覆盖在车牌中间。这一切都很好。
但是,我已经导入了自定义车牌字体 (LicensePlate.ttf)。为了调试我的代码内 SVG 图像,我制作了一个实际的 svg 图像文件,我在浏览器中打开它以确保它看起来正确,它确实如此。
问题是当最终的 JPEG 文件被创建时,它不包含我的自定义字体。相反,它依赖于 Verdana。
我的问题是,有什么方法可以在创建清晰图像的同时保持 SVG 字体?
谢谢!
完整代码
function createImage(platenumber) {
//Trying to create some sort of responsiveness
let fontsize = 80;
let letterspace = 10;
let width = 300;
let height = 90;
let x = 0;
let y = -45;
const inputlength = platenumber.length;
//Minumum Length
if (inputlength == 2) {
x = -200;
}
if (inputlength == 3) {
x = -150;
}
if (inputlength == 4) {
x = -130;
}
if (inputlength == 5) {
x = -105;
}
if (inputlength == 6) {
x = -65;
}
try {
console.log('stream is duplex, ', pipe instanceof stream.Duplex);
//Read the svg code into a buffer with a passed in plate number
const svg = new Buffer(
`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="${x} ${y} 500 40">
<defs>
<style type="text/css">
<![CDATA[
@font-face {
font-family: LicensePlate;
src: url('LicensePlate.ttf');
}
svg {
width: 100%;
height: 100%;
}
]]>
</style>
</defs>
<text x="0" y="0" font-family="LicensePlate" font-size="${fontsize}" letter-spacing="${letterspace}">
${platenumber.toUpperCase()}
</text>
</svg>`
);
const plateid = rand.generate(10);
//Create a write stream to a randomly generated file name
const write = new fs.createWriteStream(`plates/${plateid}.jpg`);
//Create the sharp pipeline
const pipeline = pipe
.overlayWith(svg, { gravity: sharp.gravity.center })//we center the svg image over the top of whatever image gets passed into the pipeline
.jpeg();//we convert to JPG because it is a compressed file format and will save space (we could also do webp if we really want to be slick about it)
//Create the read stream from the license plate template
const read = new fs.createReadStream('plate-2.png')
.pipe(pipeline)//pipe out sharp pipeline
.pipe(write);//add the write stream so that our sharp pipeline knows where to put the image
return plateid;
} catch (e) {
console.log(e);
return null;
}
}
SVG 图像
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="90" viewBox="0 -50 500 40">
<defs>
<style type="text/css">
<![CDATA[
@font-face {
font-family: LicensePlate;
src: url('LicensePlate.ttf');
}
]]>
</style>
</defs>
<text x="0" y="0" font-family="LicensePlate" font-size="150" letter-spacing="10">
Pl@T3#
</text>
</svg>
精确字体
这是我使用的确切字体的链接 http://www.fontspace.com/dave-hansen/license-plate