Why jspdf seems to add padding to this image - reactjs

I need the Image to fill the whole pdf and the pdf height and width have to come from the image
I tested the image and there is no problems with just the image file
exportToPDF = () => {
var imgData = this.state.canvasRef.toDataURL("image");
var image = new Image();
image.src = imgData;
document.body.appendChild(image)
var pdf = new jsPDF("l", "px", [this.state.canvasRef.getWidth(), this.state.canvasRef.getHeight()]);
pdf.addImage(image, 'png', 0, 0);
pdf.save("download.pdf");
console.log("export to PDF clicked");
}

I can't see where you are putting your image into the canvas but I assume you are doing something like this: https://www.w3schools.com/graphics/tryit.asp?filename=trycanvas_image. If so then the padding could be being added before you are using jspdf.
In this example the line ctx.drawImage(img, 10, 10); is adding padding to the image on the canvas. If this is whats happening to you then change this line to ctx.drawImage(img, 0, 0); and then change the height and width of your canvas tag to match the size of your img tag.

Related

Upload Image Width and Height get in react

I am new to React and react hook I want to upload an image from anywhere but I want to know the width and height of a select image before storing it in the database. I want to store the original image metadata width and height. anyone can help me
One solution can be to use FileReader, something like this should work:
const image = new Image();
let fr = new FileReader();
fr.onload = function() {
if (fr !== null && typeof fr.result == "string") {
image.src = fr.result;
}
};
fr.readAsDataURL(inputFile);
image.onload = async function() {
const width = image.width;
};
You can take a look here: https://github.com/toncic/Image-Classification/blob/master/src/Components/ImageClassification.tsx#L45

jsPDF muliple pages with div height - unable to determine the height

I am trying to generate a pdf from html divs with dynamic height and width. Below is the code.
let pages = this.rootDataContainer.nativeElement.getElementsByClassName('pdfpage');
for (let i = 0; i < pages.length; i++) {
this.pdfDoc.addHTML(pages[i], 0, 0, options, () => {
let pxHeight = pages[i].offsetHeight / scaleFactor;
this.pdfDoc.addPage(0, pxHeight);
this.counter = this.counter - 1;
});
}
There are couple of issues I am facing.
As addHTML is async, pages are added to pdf in random way.
height of the pdf page is either getting more or less height.
is there any way to set pdf size and sync the order of pages.
To sync I would use a recursive approach as in:
EDITED:
var pages = document.getElementsByClassName("pdfpage");
var pdfDoc = new jsPDF('p', 'pt', [0, 0]);
pdfDoc.deletePage(1);
pdfDoc.addPage(pages[0].clientWidth, pages[0].clientHeight);
var addDivToPdf = function(pageNr) {
pdfDoc.addHTML(pages[pageNr], 0, 0, {background:"#FFF"}, () => {
if (++pageNr < pages.length) {
//New added DIV dimensions here
pdfDoc.addPage(pages[pageNr].clientWidth, pages[pageNr].clientHeight);
addDivToPdf(pageNr);
} else {
pdfDoc.save("sample-file.pdf");
}
});
};
Notice I haven't use a for loop. This way the next page is added only when the previous is complete.
For the height, I'm not sure, scaleFactor must have the wrong units. It is not really clear if you want all pages to have the same size or you want different sizes to match the DIV height.
UPDATE: To control the widht and height according with the DIVs sizes, I have indicated 'pt' in the pdfDoc constructor:
var pdfDoc = new jsPDF('p', 'pt', [0, 0]);
However the first page appears to have always an standard size, so I have deleted it and added again with the desired size before adding the first DIV. The other pages can follow the normal flow:
pdfDoc.deletePage(1);
pdfDoc.addPage(pages[0].clientWidth, pages[0].clientHeight);
The CodePen is updated:
https://codepen.io/zameb/pen/BdbEVr

Convert SVG to image in PNG

i am converting angular nvd3 chart to svg using html2canvas and canvg plugings but when i convert pie chart to png then i looks same as chart but when i convert line chart or area chart then its background goes to black and some circle drown on image.
My code is
var svgElements = $("#container").find('svg');
//replace all svgs with a temp canvas
svgElements.each(function () {
var canvas, xml;
// canvg doesn't cope very well with em font sizes so find the calculated size in pixels and replace it in the element.
$.each($(this).find('[style*=em]'), function (index, el) {
$(this).css('font-size', getStyle(el, 'font-size'));
});
canvas = document.createElement("canvas");
canvas.className = "screenShotTempCanvas";
//convert SVG into a XML string
xml = (new XMLSerializer()).serializeToString(this);
// Removing the name space as IE throws an error
xml = xml.replace(/xmlns=\"http:\/\/www\.w3\.org\/2000\/svg\"/, '');
//draw the SVG onto a canvas
canvg(canvas, xml);
$(canvas).insertAfter(this);
//hide the SVG element
////this.className = "tempHide";
$(this).attr('class', 'tempHide');
$(this).hide();
});
html2canvas($("#container"), {
onrendered: function (canvas) {
var a = document.createElement("a");
a.download = "Dashboard.png";
a.href = canvas.toDataURL("image/png");
a.click();
var imgData = canvas.toDataURL('image/png');
var doc = new jsPDF('p', 'mm','a4');
var width = doc.internal.pageSize.width;
var height = doc.internal.pageSize.height;
doc.addImage(imgData, 'PNG', 0, 0, width, height);
doc.save('Dashboard.pdf');
}
});
$("#container").find('.screenShotTempCanvas').remove();
$("#container").find('.tempHide').show().removeClass('tempHide');
Help me guys.
Thanks In Advance
Your svg elements are being styled by the external stylesheet nv.d3.min.css .
canvg seems unable to access external style sheets, so you need to append it directly in your svg node.
To do so, if your style sheet is hosted on the same domain as your scripts, you can do something like :
var sheets = document.styleSheets;
var styleStr = '';
Array.prototype.forEach.call(sheets, function(sheet){
try{ // we need a try-catch block for external stylesheets that could be there...
styleStr += Array.prototype.reduce.call(sheet.cssRules, function(a, b){
return a + b.cssText; // just concatenate all our cssRules' text
}, "");
}
catch(e){console.log(e);}
});
// create our svg nodes that will hold all these rules
var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
var style = document.createElementNS('http://www.w3.org/2000/svg', 'style');
style.innerHTML = styleStr;
defs.appendChild(style);
// now append it in your svg node
thesvg[0].insertBefore(defs, thesvg[0].firstElementChild);
So now you can call the XMLSerializer, and canvg will be happy.
(note that this is not only a canvg limitation, the same applies for every way to draw an svg on a canvas).
Forked plunkr, where I copied the nv.d3.min.css's content to a same-origin style.css.
Very late to the conversation but I just wanted to add that the solution as described by Kaiido, put very simply, is to embed the styles into the SVG document directly.
In order to do this, you manipulate the DOM to make the SVG element look like this:
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" version="1.1">
<defs>
<style>
.rectangleStyle{
width:200px;
height:100px;
stroke:black;
stroke-width: 6;
fill: green;
}
</style>
</defs>
<rect class="rectangleStyle"/>
</svg>

WPF FlowDocument Displays *Some* Images But Not Others

This is the code I'm using to create the Image that I'm inserting into a FlowDocument.
private static Image GetImage(string url)
{
if (url == null) throw new ArgumentNullException("url");
if (!(url.StartsWith("http://") || url.StartsWith("https://") || url.StartsWith("ftp://")))
return null;
var uri = new Uri(url, UriKind.Absolute);
var bmpImg = new BitmapImage(uri)
{
CacheOption = BitmapCacheOption.OnDemand,
};
if (bmpImg.CanFreeze) bmpImg.Freeze();
var img = new Image
{
Source = bmpImg,
Stretch = Stretch.Uniform,
Height = 120,
Width = 120,
};
return img;
}
When I create a document and insert an image from my server with
Designer.CaretPosition.Paragraph.Inlines.Add(image);
everything works fine - image displays as expected. Also, the main Google Logo image works fine, but the HackaDay Logo and others just display a blank image.
What could be the reason for this?
I think that some websites have hotlink protection. For example in my website I can link a photo in every page that it is in my domain and it works well, however if you try to link a photo in other domain, the photo doesn't load.

how to add png for a image in code for silverlight?

Try to create a image in code as below:
sp = new StackPanel() { Orientation = Orientation.Horizontal };
Image myImage = new Image() { HorizontalAlignment = HorizontalAlignment.Left, Width = 16, Height = 16, Margin = new Thickness(1, 0, 0, 0) };
MyImage.Source = new BitmapImage(new Uri("/MyAssembly;component/folder/image1.png", UriKind.RelativeOrAbsolute));
sp.Children.Add(MyImage);
then run the app, the image does not display. Check the data with Fiddler and got 404 error. The source for above image is something like:
http://localhost:80/MyAssembly;component/folder/image1.png
but this image is complied into an assembly MyAssembly.
It is okay to get the image xaml from the assembly with following markup:
<Image Source="/MyAssembly;component/folder/image1.png"/>
Confused. Not sure why. How to get dynamic image in code?
Updated: Thanks for information form Clemens. Try following code:
sp = new StackPanel() { Orientation = Orientation.Horizontal };
ImageSourceConverter converter = new ImageSourceConverter();
Image myImage = new Image() { HorizontalAlignment = HorizontalAlignment.Left, Width = 16, Height = 16, Margin = new Thickness(1, 0, 0, 0) };
MyImage.Source = (ImageSource)converter.ConvertFromString("/MyAssembly;component/folder/image1.png");
sp.Children.Add(MyImage);
the result same as before. message from Fiddler:
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
The resource for this still is
http://localhost:80/MyAssembly;component/folder/image1.png.
Don't know what scheme to use for that Uri in Silverlight, where you would write something like pack://application,,,/MyAssembly;component/folder/image1.png in WPF.
But fortunately you could always write this:
ImageSourceConverter converter = new ImageSourceConverter();
MyImage.Source = (ImageSource)converter.ConvertFromString(
"/MyAssembly;component/folder/image1.png");
It is of course also possible to explicitly set a relative URI:
MyImage.Source = new BitmapImage(
new Uri("/MyAssembly;component/folder/image1.png", UriKind.Relative));
Note however that the Build Action for image1.png has to be set to Resource in any case.

Resources