Open fubuk-i opened 3 years ago
hey @fubuk-i , Did you find the solution?
i have the same problem. Thinking about extracting the image-tags attributes and use them for x,y-coordinates and an img-id to replace the images at their position from my svg's on file system... since i have all the images in plain svg format already, but they got converted when i put them together in a new graphic... Other option could be to convert the svg to svg in a way that the image-tags would be replaced..... Or just find a library not struggeling with image-tags xD
Also succesfully converted y svg to png and then to pdf using svg2img lib, but it still suffers in quaity so far.
I managed to get this working for both SVGs & raster images.
The strategy is:
<image href='path/image.svg'>
): download & embed the external SVGs into the printed SVG.<image href='path/image.png'>
): download them & serve using imageCallback.Example code:
import axios from 'axios'
// (...)
// svgNode is the SVGElement to be printed
const svgToPrint = svgNode.cloneNode(true) as SVGElement // we clone it as we're going to do some in-place changes
const imageTags = svgToPrint.querySelectorAll('image')
const http = axios.create() // axios for http requests
const hrefToData: { [key: string]: ArrayBuffer } = {} // map for storing raster images
for (const imageTag of imageTags) { // iterate over all image tags
const href = imageTag.getAttribute('href')
if (href?.endsWith('.svg')) {
// download svgs & embed them into the original svg
const img = await http.get(href)
const parser = new DOMParser()
const newSvg = parser.parseFromString(img.data, 'image/svg+xml').getElementsByTagName('svg')[0]
for (const attrName of ['x', 'y', 'width', 'height']) {
const val = imageTag.getAttribute(attrName)
if (val !== null) {
newSvg.setAttribute(attrName, val)
}
}
imageTag.replaceWith(newSvg)
} else if (href !== null) {
// download other images (pngs, jpegs, ..) as "ArrayBuffer" (binary) and remember them
const imgResponse = await http.get(href, { responseType: 'arraybuffer' })
hrefToData[href] = imgResponse.data
}
}
const doc = new (window as any).PDFDocument({ size: paperSize, layout })
const chunks: any[] = []
doc.pipe({
write: (chunk: any) => chunks.push(chunk),
end: () => {
const pdfBlob = new Blob(chunks, {
type: 'application/octet-stream'
})
window.open(URL.createObjectURL(pdfBlob))
},
on: () => {},
once: () => {},
emit: () => {}
})
SVGtoPDF(doc, svgToPrint.outerHTML, 0, 0, {
// provide the raster images using this callback
imageCallback: (href) => {
return hrefToData[href]
}
})
doc.end()
For reference, here are some code pointers in the SVG-to-PDFKit and PDFKit handling the images:
I am using SVGtoPDF npm library to get svg element on pdf but for following svg object it is not working as
<image>
tag is creating problem.ERROR Message:: SVGElemImage: failed to open image "http://174.138.12.68:4000/uploads/products/1597070187552-Ash%20Back.jpg" in PDFKit
My SVG data::