image processing by Opencvjs - javascript

I'm trying to convert an image using prewitt method using javascript. When I run it I get this error:
BindingError {name: 'BindingError', message: 'Cannot pass "array([[ 1, 1, 1],\n [ 0, 0, 0],\n [-1,-1,-1]])" as a Mat', stack: 'BindingError: Cannot pass "array([[ 1, 1, 1],\n …p://localhost:3000/static/js/1.chunk.js:103232:9)'}
Error at Filter2D
const prewitt=new cv.Mat()
const KERNEL_X=np.array([[1,1,1],[0,0,0],[-1,-1,-1]])
const KERNEL_Y=np.array([[-1,0,1],[-1,0,1],[-1,0,1]])
let img_prewittx=cv.filter2D(img,prewitt,-1,KERNEL_X)
let img_prewitty=cv.filter2D(img,prewitt,-1,KERNEL_Y)
cv.imshow(this.prewittRef.current,img_prewittx,img_prewitty)

Here is a good example for using cv.filter2D by OpenCV.js.
The type of the kernel argument should be cv.Mat() and not np.array (it's not Python where we can use np.array as OpenCV Mat).
The destination matrix is stored in the second argument of cv.filter2D (it is not returned as in Python).
It is recommended to apply the filter on Grayscale input (especially not on BGRA input, because the output alpha channel may be fully transparent).
Assume gray is the input image.
Apply cv.filter2D as follows:
const KERNEL_X = cv.matFromArray(3, 3, cv.CV_32FC1, [1,1,1, 0,0,0, -1,-1,-1]);
cv.filter2D(gray, img_prewittx, -1, KERNEL_X)
Complete code sample:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello OpenCV.js</title>
</head>
<body>
<p id="status">OpenCV.js is loading...</p>
<div>
<div class="inputoutput">
<img id="imageSrc" alt="No Image" />
<div class="caption">imageSrc <input type="file" id="fileInput" name="file" /></div>
</div>
<div class="inputoutput">
<canvas id="canvasOutput" ></canvas>
<div class="caption">canvasOutput</div>
</div>
</div>
<script async src="opencv.js" type="text/javascript"></script>
<script type="text/javascript">
let imgElement = document.getElementById('imageSrc');
let inputElement = document.getElementById('fileInput');
inputElement.addEventListener('change', (e) => {
imgElement.src = URL.createObjectURL(e.target.files[0]);
}, false);
//Read image and execute the OpenCV code sample.
imgElement.onload = function () {
let img = cv.imread(imgElement);
let gray = new cv.Mat()
let img_prewittx = new cv.Mat();
let img_prewitty = new cv.Mat();
if (img.channels() == 4)
{
cv.cvtColor(img, gray, cv.COLOR_BGRA2GRAY); //Convert from BGRA to Grayscale.
}
else if (img.channels() == 3)
{
cv.cvtColor(img, gray, cv.COLOR_BGR2GRAY); //Convert from BGR to Grayscale.
}
else
{
gray = img.clone();
}
//const prewitt = new cv.Mat()
//const KERNEL_X = np.array([[1,1,1],[0,0,0],[-1,-1,-1]])
//const KERNEL_Y = np.array([[-1,0,1],[-1,0,1],[-1,0,1]])
const KERNEL_X = cv.matFromArray(3, 3, cv.CV_32FC1, [1,1,1, 0,0,0, -1,-1,-1]);
const KERNEL_Y = cv.matFromArray(3, 3, cv.CV_32FC1, [-1,0,1, -1,0,1, -1,0,1]);
//https://answers.opencv.org/question/224848/how-do-i-create-and-use-a-custom-kernel-with-cvfilter2d/
cv.filter2D(gray, img_prewittx, -1, KERNEL_X)
cv.filter2D(gray, img_prewitty, -1, KERNEL_Y)
cv.imshow('canvasOutput', img_prewittx); //Show img_prewittx for testing
img.delete();
gray.delete();
img_prewittx.delete();
img_prewitty.delete();
};
//check openCV
var Module = {
// https://emscripten.org/docs/api_reference/module.html#Module.onRuntimeInitialized
onRuntimeInitialized() {
document.getElementById('status').innerHTML = 'OpenCV.js is ready.';
}
};
</script>
</body>
</html>

Related

How to Get Random Name and Image from JSON for each Object in JavaScript

I want to create a random ruffling game where it randomly chooses the name and image of a certain user.
My problem is how would every image be linked to that specific user when it starts ruffling randomly, the image and name may not match.
I want it such that every object in the json array that has a name and an image to be matched when picking randomly
How can i do that?
here is my code:
script.js
const ENTRANTS = [{
name:"John",
image:"images/sun-rise.jpg"
},{
name:"Jack",
image:"images/tree-736885__480.jpg"
},{
name:"Jane",
image:"images/pexels-anjana-c-674010.jpg"
}];
const rollEl = document.querySelector(".roll");
const rollAgainEl = document.querySelector(".roll-again");
const namesEl = document.querySelector(".names");
const imageEl = document.querySelector(".image");
const winnerEl = document.querySelector(".winner");
const boxEl = document.querySelector(".text-box");
const winnerTextELEMENT = document.querySelector(".winnerText");
const values = Object.values(ENTRANTS)
winnerTextELEMENT.classList.add('hide')
function randomName() {
const rand = Math.floor(Math.random() * values.length);
const name = values[rand].name;
const image = values[rand].image;
namesEl.innerText = name;
imageEl.src = image
}
function rollClick() {
boxEl.classList.remove("hide")
rollEl.classList.add("hide");
rollAgainEl.classList.add("hide");
winnerEl.classList.add("hide");
namesEl.classList.remove("hide");
setDeceleratingTimeout(randomName, 10, 30);
setTimeout(() => {
namesEl.classList.add("hide");
winnerEl.classList.remove("hide");
rollAgainEl.classList.remove("hide");
const winner = namesEl.innerText;
winnerEl.innerText = winner;
winnerTextELEMENT.classList.remove('hide')
}, 4000);
}
function setDeceleratingTimeout(callback, factor, times) {
const internalCallback = ((t, counter) => {
return () => {
if (--t > 0) {
setTimeout(internalCallback, ++counter * factor);
callback();
}
};
})(times, 0);
setTimeout(internalCallback, factor);
}
index.html:
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Ruffle</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel="stylesheet" href="./style.css">
</head>
<body>
<button class="roll" onclick="rollClick()">Start</button>
<span class="winnerText">WINNER</span>
<div class="text-box hide">
<img class="image" src=""/>
<div class="names hide">
</div>
<div class="winner hide"></div>
</div>
<button class="roll-again hide" onclick="rollClick()"> Start Again</button>
<script src="./script.js"></script>
</body>
</html>
Create Two Arrays using the names and images value. Use Math.Floor(Math.random * array.length)For both of the arrays to get a random value that you can use an index value for the array so you get a random index value. Then use the random number/index value to get the random name and picture you want.
You should convert the JSON into a array then do MyArray[Math.round((Math.random()*number) * 10000) / 10000] and you may get the image and name that you want selected this is all in Javascript of course

How to implement custom Tensorflow.js models into webpage?

I would like to create a website that can classify different types of cars. I have managed to get the website working to use the mobile net model, but I would like to use a custom model that I trained in google colab and then converted into javascript. Does anyone know how I could achieve this?
Here is the javascript code:
// Defining Variables
const webcamElement = document.getElementById('webcam');
let net;
var webcamrunning = false; // Flag, indicates if webcam-prediction is running or not
var bw = document.getElementById('butwebcam')
var bi = document.getElementById('butimage')
// App that predicts image
async function app() {
console.log('Loading mobilenet..');
const uploadJSONInput = document.getElementById('upload-json');
const model = await tf.loadLayersModel(tf.io.browserFiles([uploadJSONInput.files[0]]));
// Check if model loaded, if not, load it.
if (net == undefined)
{bi.innerHTML = 'Wait for Initiation...';
net = await model.load();
console.log('Sucessfully loaded model');
bi.innerHTML = 'Predict'}
else {console.log('Model already loaded')};
// Make a prediction through the model on our image.
const imgEl = document.getElementById('output');
const result = await net.classify(imgEl);
document.getElementById('console_pic').innerText =
`Prediction: ${result[0].className}
Probability: ${Math.round(result[0].probability*100)} %
`;
}
// Function that activates (starts webcam app) and deactivates the Webcam-Prediction
function start_webcam(){
if (webcamrunning == false)
{app_webcam();
}
else {webcamrunning = false;
bw.innerHTML = 'Activate Predicting';
};
};
// Setup Webcam
async function setupWebcam() {
return new Promise((resolve, reject) => {
const navigatorAny = navigator;
navigator.getUserMedia = navigator.getUserMedia ||
navigatorAny.webkitGetUserMedia || navigatorAny.mozGetUserMedia ||
navigatorAny.msGetUserMedia;
if (navigator.getUserMedia) {
navigator.getUserMedia({video: true},
stream => {
webcamElement.srcObject = stream;
webcamElement.addEventListener('loadeddata', () => resolve(), false);
},
error => reject());
} else {
reject();
}
});
}
// Webcam application
async function app_webcam() {
console.log('Loading mobilenet..');
// Check if model loaded, if not, load it.
if (net == undefined)
{bw.innerHTML = 'Wait for Initiation...';
net = await mobilenet.load();
console.log('Sucessfully loaded model');}
else {console.log('Model already loaded')};
await setupWebcam();
webcamrunning =true;
bw.innerHTML = 'Stop Predicting';
while (webcamrunning) {
const result = await net.classify(webcamElement);
document.getElementById('console_vid').innerText =
`Prediction: ${result[0].className}
Probability: ${Math.round(result[0].probability*100)} %
`;
// Give some breathing room by waiting for the next animation frame to
// fire.
await tf.nextFrame();
}
}
;
Here is the html code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel='stylesheet' href='styles.css'/>
<input type="file" id="upload-json" src="C:\Users\USER\Desktop\ImageClassifier-master\model\model.json"/>
<!-- Load the latest version of TensorFlow.js -->
<script src="https://unpkg.com/#tensorflow/tfjs"></script>
<script src="https://unpkg.com/#tensorflow-models/mobilenet"></script>
<title> Image Classifier with MobileNet </title>
</head>
<body>
<img style='margin-top: -6px; z-index: 19;' id="header" height ="320">
<h1 style='margin-top: -35px'> What car is that?</h1>
<br>
<hr/>
<br>
<em> <strong> </strong> </em>
<br>
<br>
<hr/>
<br>
<h2> Upload your own Picture</h2>
<!-- Upload Function with File Preview -->
<input type="file" accept=".png, .jpg, .jpeg" height="200"
onchange="document.getElementById('output').src = window.URL.createObjectURL(this.files[0])">
<!-- Predict button, calls predict function in Javascript -->
<button id="butimage" onclick="app()"> Predict! </button>
<!-- Window for Picture Preview -->
<div class = "window">
<span class="helper"></span>
<img class="center" id="output" alt="your image" src = "img/example.jpg" />
</div>
<div class = "result" id="console_pic">Result</div>
<br>
<hr/>
<br>
<br>
<br>
<br>
<script src="index.js"></script>
</body>
</html>

Loading images uploaded with a form not showing

The user uploads images with a form. The images should all be displayed in the canvas. Only one of multiple images shows. Maybe the images are not properly loaded?
html:
let value = 0;
var images = [];
function setup() {
createCanvas(320, 270);
background(0);
const form = document.querySelector('form');
frameRate(2);
form.addEventListener('submit', e => {
e.preventDefault();
var preview = document.querySelector('img'); //selects the query named img
var files = form.querySelector('[type=file]').files;
if (files[0]) {
for(let i = 0; i < files.length; i++){
var reader = new FileReader();
reader.onloadend = function () {
//preview.src = reader.result;
images[i] = loadImage(reader.result);
console.log('new image added')
console.log(images[i]);
}
reader.readAsDataURL(files[i]); //reads the data as a URL
}
}
});
}
let cursor = 0;
function draw() {
background(0);
if(images.length > 0){ image(images[cursor], 0, 0, width, height - 20); }
cursor ++;
if(cursor >= images.length){ cursor = 0}
fill(255);
textSize(16);
text(value, 10, height - 10);
console.log(cursor);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>image_classification</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.dom.min.js"></script>
<script src="https://unpkg.com/ml5#0.1.1/dist/ml5.min.js"></script>
<script src="sketch.js"></script>
</head>
<body>
<h1>Welcome to the site!</h1>
<form id="imgs" method="post" enctype="multipart/form-data">
images:
<input type="file" name="files[]" multiple>
<input type="submit" value="Upload File" name="submit">
</form>
<br/>
</body>
</html>
I have no idea where the problem even lays. Is it me inserting the images into the array incorrectly, or am I doing something wrong with the asynchronous nature of JavaScript?
Thanks in advance.
Your problem is caused by JavaScript scoping.
Take a look at this part of your code:
for(let i = 0; i < files.length; i++){
var reader = new FileReader();
reader.onloadend = function () {
images[i] = loadImage(reader.result);
}
reader.readAsDataURL(files[i]);
}
Because you're using the var keyword, your reader is actually in function scope. From MDN:
The scope of a variable declared with var is its current execution context, which is either the enclosing function or, for variables declared outside any function, global. If you re-declare a JavaScript variable, it will not lose its value.
This is why your reader variable only appears to work for one of your images.
The simplest fix to this is to use const instead of var here:
const reader = new FileReader();
The const keyword creates variables in block scope which is probably what you expected var to do in the first place.

Draw image to canvas with Pixabay API (Jquery)

The JSFIDDLE
Here is my problem:
I want to draw the image in the second line of the console when I double click on "Get JSON DATA", in my canvas.
I hope that was clear.
I think it's a bit difficult...
Here is my code :
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<canvas id="test1" width="200px" height="200px"> </canvas>
<input id="urlBanner" type="text" style="width:450px;" maxlength="100">
<button type="button" value="Get JSON Data" onclick="getUrlBanner()">Get JSON data</button>
<script>
function getUrlBanner()
{
var urlBanner = document.getElementById("urlBanner").value;
console.log(urlBanner);
var urlAPI = "https://pixabay.com/api/?key=10642718-3227f97c509ef5fe89537eec9&q=";
//var full = "full:" + urlBanner;
//console.log(full);
$(document).ready(function(){
$("button").click(function(){
fetch(urlAPI+urlBanner+"&image_type=photo")
.then(res => res.json())
.then((out) => {
var img = out.hits[0].largeImageURL;
document.getElementById('test1').src = img;
console.log(img);
console.log("full : " + urlAPI+urlBanner+"&image_type=photo");
}).catch(err => console.error(err));
});
});
}
$(document).ready(function() {
$('#test1').each(function() {
var myCanvas = document.getElementById('test1');
var ctx = document.getContext('2d');
var img = new Image;
img.onload = function(){
ctx.drawImage(img[0],10,10);
};
img.src = 'UrlBanner';
});
});
</script>
</body>
</html>
My API works properly, that's ok.
In fact, the problem is really here I think
$(document).ready(function() {
$('#test1').each(function() {
var myCanvas = document.getElementById('test1');
var ctx = document.getContext('2d');
var img = new Image;
img.onload = function(){
ctx.drawImage(img[0],10,10);
I can't get it...
The jpg file in console need to appear in my canvas.
Thanks in advance,

Duplicate content in pdf created using jsPDF

I am using jsPDF to convert html to pdf. In some cases, where html has svg charts, some of the data is duplicated in the generated pdf.
e.g. If the charts have legends, they are getting duplicated. See the screenshot below. City names and the percentages are repeated.
Below is the code to create pdf.
pdf.addHTML($("#page1"), options, function(){
pdf.addPage();
pdf.addHTML($("#page2"), options, function(){
pdf.addPage();
pdf.output('dataurlnewwindow');
});
});
EDIT 1:
This is what I have figured so far.
<div id="outerDiv">
<div id="pieChart"></div>
</div>
When I do this, pdf.addHTML($("#pieChart"), no issues here.
But, when I do this, pdf.addHTML($("#outerDiv"), then labels get repeated.
and this is how I generate my c3js charts
var pieChart = c3.generate({
bindto: '#pieChart',
EDIT 2:-
Below is my entire code.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script type="text/javascript" src="http://gabelerner.github.io/canvg/rgbcolor.js"></script>
<script type="text/javascript" src="http://gabelerner.github.io/canvg/StackBlur.js"></script>
<script type="text/javascript" src="http://gabelerner.github.io/canvg/canvg.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.2.61/jspdf.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.5.0-alpha1/html2canvas.js"></script>
<script type='text/javascript'>
function replaceAllSVGsWithTempCanvas(elemSelector) {
var svgElements = $(elemSelector).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).attr('class', 'tempHide');
$(this).hide();
});
}
jQuery(document).ready(function($) {
genChart();
});
function genPDF() {
var options = {
background: '#fff'
};
var pdf = new jsPDF('p', 'pt', 'a4');
replaceAllSVGsWithTempCanvas(".content");
pdf.addHTML($("#chartOuter"), options, function() {
pdf.output('dataurlnewwindow');
$(".content").find('.screenShotTempCanvas').remove();
$(".content").find('.tempHide').show().removeClass('tempHide');
});
}
function genChart() {
var chart = c3.generate({
data: {
columns: [
['data1', 30],
['data2', 120],
],
type: 'pie'
}
});
}
</script>
</head>
<body class="content">
<table width="100%">
<tr>
<td width="50%">
<div id="chartOuter">
<div id="chart"></div>
</div>
</td>
</tr>
<tr>
<td colspan="2" align="left">
<input type="button" onclick="genPDF();" value="Generate PDF" />
</td>
</tr>
</table>
</body>
</html>
EDIT 3:-
I tried just converting html to canvas using html2canvas. It is also giving the same issue.
Edit 4:
I could fix the duplicate issue now. But the charts and the text written to pdf are little bit blurry. Basically, I added function replaceAllSVGsWithTempCanvas and then use that while writing to pdf. But it seems this function does smething to the html that makes content written to pdf blurry. In fact pie charts etc, are no more circles but looks like oval shape.
Edited the question with modified js.
Looks like it is a bug in html2canvas. You should add the bottom code after html2canvas is loaded to fix that (Credits goes to this guy):
NodeParser.prototype.getChildren = function(parentContainer) {
return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) {
var container = [node.nodeType === Node.TEXT_NODE && node.parentElement.tagName !== "text" ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement);
return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== "TEXTAREA" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container;
}, this));
};
Fiddle
Since html2canvas loads as a module, you should directly find NodeParser.prototype.getChildren in the source code and edit it to match above. That means you can't load it from CDN.
I think made it work correctly in two steps.
First, I commented out the "addhtml plugin" because I had this error in my console:
Refused to execute script from 'https://raw.githubusercontent.com/MrRio/jsPDF/master/plugins/addhtml.js' because its MIME type ('text/plain') is not executable, and strict MIME type checking is enabled.
Second, I changed the pdf source from #chartOuter to #chart.
pdf.addHTML($("#chart"), options, function () {
var string = pdf.output('datauristring');
$('.preview-pane').attr('src', string)
});
And there is no more dedoubling.
-----
EDIT (since I misunderstood the question at first)
It is needed to use the outer div... And maybe the full page.
Okay... To be honest, I don't know why this text issue happens.
But I noticed that the duplicate text has serif even if it is specified "sans-serif".
So I focused on this.
I tried to change the font-size... It affected the duplicate, but the text didn't follow the css rule. Okay.
Then I tried to just remove the text before the pdf creation part... And magic!
;)
$(".c3 svg").css({"font-size":"0px"});
Here is the complete script, I didn't touch the rest of your original code.
jQuery(document).ready(function ($) {
genChart();
});
function genPDF() {
var options = { background: '#fff'};
var pdf = new jsPDF('p', 'pt', 'a4');
$(".c3 svg").css({"font-size":"0px"}); // <-- This does the trick !
pdf.addHTML($("#chartOuter"), options, function () {
var string = pdf.output('datauristring');
$('.preview-pane').attr('src', string)
});
}
function genChart() {
var chart = c3.generate({
data: {
columns: [
['data1', 30],
['data2', 120],
],
type : 'pie'
}
});
}
You can try using ChartJS instead of C3.
I've adapted your code and tried it with success.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<!-- <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.2.61/jspdf.debug.js"></script> -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.2.61/jspdf.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.5.0-alpha1/html2canvas.js"></script>
<script type="text/javascript" src="https://raw.githubusercontent.com/MrRio/jsPDF/master/plugins/addhtml.js"></script>
<script type='text/javascript'>
jQuery(document).ready(function ($) {
genChart();
});
function genPDF() {
var options = { background: '#fff'};
var pdf = new jsPDF('p', 'pt', 'a4');
pdf.addHTML($("#chartOuter"), options, function () {
var string = pdf.output('datauristring');
$('.preview-pane').attr('src', string)
});
}
function genChart () {
var ctx = $("#chart");
var options = {};
var myPieChart = new Chart(ctx, {
type: 'pie',
data: {
labels: [
"data1",
"data2"
],
datasets: [{
data: [30, 120],
backgroundColor: [
"#FF6384",
"#36A2EB"
],
hoverBackgroundColor: [
"#FF6384",
"#36A2EB"
]
}]
},
options: options
});
}
</script>
</head>
<body>
<table width="100%">
<tr>
<td width="50%">
<div id="chartOuter">
<!-- <div id="chart"></div> -->
<canvas id="chart" width="400" height="400"></canvas>
</div>
</td>
<td>
<iframe height="550px" class="preview-pane" type="application/pdf" width="100%" frameborder="0" style="position:relative;z-index:999"></iframe>
</td>
</tr>
<tr>
<td colspan="2" align="left">
<input type="button" onclick="genPDF();" value="Generate PDF"/>
</td>
</tr>
</table>
</body>
</html>
Dynamically loading pdf blurry, the same file official demo is very clear. I can't locate the problem?
Use the chrome browser. Version 73.0.3683.86 (official version) (64-bit)
Here is my code:
async process(buffer, index) {
// Processing the decrypted data stream
let uint8Array = new Uint8Array(buffer);
var word = await this.Uint8ToBase64(uint8Array);
var decryptedData = CryptoJS.AES.decrypt(word, this.authorKey, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
// Then turn wordArray to uint8Array
let getUint8Array = await this.wordArrayToU8(decryptedData);
// decryption ends
this.loadingPdf(getUint8Array, index);
},
async loadingPdf(getUint8Array, index) {
// render canvas
let pdf = await pdfjsLib.getDocument({ data: getUint8Array, cMapUrl: cMapUrl, cMapPacked: cMapPacked });
let page = await pdf.getPage(1).then(page => {
return page;
});
let canvas = document.getElementById("the-canvas" + index);
const CSS_UNITS = 96.0 / 72.0;
const DEFAULT_SCALE = 1.7;
const UNKNOWN_SCALE = 0;
let viewport = page.getViewport( DEFAULT_SCALE * CSS_UNITS);
if (canvas.dataset.runed) return;
canvas.width = viewport.width*CSS_UNITS;
canvas.height = viewport.height*CSS_UNITS;
this.canvasW =
this.canvasW > (1000 / viewport.height) * viewport.width
? this.canvasW
: (1000 / viewport.height) * viewport.width;
canvas.style.width = (1000 / viewport.height) * viewport.width;
canvas.dataset.runed = true;
var context = canvas.getContext('2d');
// [Important] Turn off anti-aliasing
context.mozImageSmoothingEnabled = false;
context.webkitImageSmoothingEnabled = false;
context.msImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
await page.render({
//enableWebGL: true,
// canvasContext: context,
transform: [CSS_UNITS, 0, 0, CSS_UNITS, 0, 0],
// transform: [1, 0, 0, 1, 0, 0],
canvasContext: canvas.getContext("2d"),
viewport: viewport
});
this.loadedPages.push(index)
},

Categories