file input to blob using canvas - javascript

unable to insert blob to indexedDB please assint in inserting blob from file to indexedDB :)
CODE
<html>
<head>
<title>file to BLOB</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div id="test">
<input id="File" type="file" accept="image/*" capture="user">
</div>
</body>
</html>
<script src="js/idbConn.js"></script>
Javascript
<script>
$(document).ready(function(){
$("#File").change(function(){
const File = this.files[0];
const cvs = document.createElement("canvas");
const optBlob = cvs.toBlob(function(cvsBlob){
let fileURL = URL.createObjectURL(File);
let imgFile = new Image();
let imgFile.src = fileURL;
imgFile.onload = function(){
cvs.width = imgFile.naturalWidth;
cvs.height = imgFile.naturalHeight;
let ctx = cvs.getContext("2d").drawImage(imgFile,0,0);
URL.revokeObjectURL(fileURL);
}
},File.type,0.3);
const data = new Object();
data.blob = optBlob;
let trx = db.transaction(["imgBlobs"],"readwrite").objectStore("imgBlobs").put(data,"test.jpeg");
});
});
</script>
trying to directly insert file into indexedDB but blob is as undefined
if kept cvsBlob in data.blob blank image is storing in indexedDB

There are a few problems.
HTMLCanvasElement.toBlob does not return anything. You get the blob in the callback function.
JavaScript is blocking, queued tasks (like the toBlob callback) events (like onload) will not run until the current execution has returned. This means that the line
const data = new Object(); is run before the toBlob callback has been called.
You are calling toBlob before you have created, loaded and drawn the image to the canvas.
let imgFile.src = fileURL; This line will throw a syntax error??
Fix
First load the image.
On image load create the canvas and draw the image on it.
Revoke the image url.
Convert the canvas to a blob.
In the toBlob callback add the blob to the DB.
Example
Call the function with the file you get from the file input. Eg $("#File").change(function() { saveImageToDB(this.files[0]) });
function saveImageToDB(file) {
const fileURL = URL.createObjectURL(file);
const img = new Image();
img.src = fileURL;
img.addEventListener("load", () => {
URL.revokeObjectURL(fileURL);
const cvs = document.createElement("canvas");
cvs.width = img.naturalWidth;
cvs.height = img.naturalHeight;
cvs.getContext("2d").drawImage(img, 0, 0);
cvs.toBlob(blob => {
// Code to add blob to database. Put your db code in here
db.transaction(["img"], "write").objectStore("imgs").put({blob}, file.name);
}, File.type, 0.3);
}, {once: true});
}

Related

How can I send a copy of a user generated png to my backend?

I am building a site that allows users to create customized graphics and then download them directly from the page.
I am doing this via the user customizing an svg via a javascript powered form which is then made into a PNG before downloading.
However, now I want to store a copy of the png that the user created so that I can display it on the site's home page. What is the best way to store a copy of the dynamically created graphic? AJAX? HTTP Request? Both are very foreign topics to me so I am unsure how to go about it from here.
For reference here is the code that builds the PNG from the svg and then triggers the download for the user.
var svg = document.getElementById("bg2");
var canvas = document.querySelector("canvas");
function triggerDownload (imgURI) {
var evt = new MouseEvent('click', {
view: window,
bubbles: false,
cancelable: true
});
if(document.getElementById("name").value=="null" || document.getElementById("name").value=="") {
var un = "MakeAGraphic";
} else {
var enteredName = document.getElementById("name").value.replace(/[^a-zA-Z ]/g, "");
var un = `${enteredName}_MakeAGraphic`
}
var a = document.createElement('a');
a.setAttribute('download', `${un}.png`);
a.setAttribute('href', imgURI);
a.setAttribute('target', '_blank');
a.dispatchEvent(evt);
}
btn.addEventListener('click', function () {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var data = (new XMLSerializer()).serializeToString(svg);
var DOMURL = window.URL || window.webkitURL || window;
var img = new Image();
var svgBlob = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
var url = DOMURL.createObjectURL(svgBlob);
img.onload = function () {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
var imgURI = canvas
.toDataURL('image/png')
.replace('image/png', 'image/octet-stream');
triggerDownload(imgURI);
};
img.src = url;
});
agree to that answer mentioned by #showdev .
Call
canvas.toBlob(callback, mimeType, qualityArgument);
then call
formData.append("an-image", blob);
then upload formData using the AJAX or fetch API.
see the documents at
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob
https://developer.mozilla.org/en-US/docs/Web/API/FormData/append
https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

Javascript canvas drawImage results in blank? -revised-

I'm working inside a lit-element component trying to draw an img element onto a canvas element:
return html`
<img></img>
<br>
<canvas width="1500" height="1500"></canvas>
<br>
<input type='file' accept='image/*' #change=${this.readImage}> </input>
`
readImage(event) {
// Get the image element
var img = this.shadowRoot.querySelector('img')
// Get the file
var file = event.target.files[0]
// File reader
var reader = new FileReader()
// Handle read
reader.onload = event=>{
img.src = event.target.result
// Get the canvas element
var canvas = this.shadowRoot.querySelector('canvas')
// Get the canvas context
var context = canvas.getContext('2d')
// Draw image on canvas
context.drawImage(img,0,0)
}
// Read the file
reader.readAsDataURL(file)
}
However for some reason the canvas element remains blank. I can't seam to find out where I'm going wrong or if I'm running into some kind of bug?
You need to use onload to make sure the image has finished loading. Is there a reason you aren't just using a new Image() object instead of using an embedded img element?
this.shadowRoot=document;
function
readImage(event) {
// Get the image element
var img = this.shadowRoot.querySelector('img')
// Get the file
var file = event.target.files[0]
// File reader
var reader = new FileReader()
// Handle read
reader.onload = event => {
img.onload = () => {
// Get the canvas element
var canvas = this.shadowRoot.querySelector('canvas')
// Get the canvas context
var context = canvas.getContext('2d')
// Draw image on canvas
context.drawImage(img, 0, 0)
}
img.src = event.target.result
}
// Read the file
reader.readAsDataURL(file)
}
<img></img>
<br>
<canvas width="1500" height="1500"></canvas>
<br>
<input type='file' accept='image/*' onchange=readImage(event)> </input>

Transfer img (file) to another page

I have a page with element
<input type="file" id="dialog-select-files" multiple="" accept="image/jpeg" name='files[]'>
After a user chooses files I want to load a new page with a gallery of selected photos.
So on my first page, I created URL, this way
URL.createObjectURL(files[i])
and saved it in cookies.
On my second page, I got URLs from cookies, created element 'img' and showed it on page:
var img = document.createElement("img");
img.src = getCookie(nameCookie);
gallery.appendChild(img);
But URL is blob URL, like
blob:http://localhost/8b67533a-f5f1-4529-8c3e-9829e6786be3 and it is not found on my second page.
How should I pass selected files from one page to another? I think I should use another way (not save in cookie), but I can't find a solution on the internet.
Thank you.
You can convert it to base64 string, then you can save it in the cookies or in the localStorage or in the sessionStorage and get it ftom there.
function img2base64(imgSrc, cb) {
var img = new Image();
// formats: image/png, image/jpeg, image/jpg, image/gif, image/bmp
var outputFormat = 'image/png';
img.onload = function() {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.naturalHeight;
canvas.width = this.naturalWidth;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
cb(dataURL);
};
img.src = imgSrc;
}
var base64Str;
img2base64(imgSrc, function(dataUrl) {
// do something
console.log(dataUrl);
base64Str = dataUrl;
localStorage.setItem('img1', dataUrl);
});

Why is this FileReader onload not firing?

I am starting with this working JavaScript code:
// Begin File Open Code.
function fileOpen()
{
var fileInput = document.getElementById('fileInput');
var fileDisplayArea = document.getElementById('iDisplay');
fileInput.addEventListener('change', function(e)
{
file = fileInput.files[0];
var imageType = /image.*/;
if (file.type.match(imageType))
{
var reader = new FileReader();
reader.onload = function(e)
{
iDisplay.innerHTML = "";
image = new Image();
image.src = reader.result;
image.id = "I"; // Add an id attribute so the image editor code can access the image.
iDisplay.appendChild(image);
image.onload = function()
{
c = document.getElementById("canvas1");
context = c.getContext("2d");
c.width = image.width;
c.height = image.height;
context.drawImage(image,0,0);
}
}
reader.readAsDataURL(file);
moreFiles++;
document.getElementById("fileInput").disabled = true;
document.getElementById("fileInputD").innerHTML = '<p>Please refresh page to open a new image</p>';
}
else
{
iDisplay.innerHTML = "File type not supported."
}
});
}
// End File Open Code
And trying to break it up into two separate functions, fileOpen() and loadImage(). The reason is that loadImage will also be used to load default images. I came up with several non-working versions. After reading about the topic here, most recently this answer Javascript FileReader onload not firing I adjusted the code as follows:
// Begin File Open Code
function fileOpen(radio)
{
fileInput = document.getElementById('fileInput');
fileDisplayArea = document.getElementById('iDisplay');
fileInput.addEventListener('change', function(e)
{
file = fileInput.files[0];
var imageType = /image.*/;
if (file.type.match(imageType))
{
reader = new FileReader();
reader.onload = fileSelected;
function fileSelected(e)
{
iDisplay.innerHTML = "";
image = new Image();
image.src = reader.result;
image.id = "I"; // Add an id attribute so the image editor code can access the image.
iDisplay.appendChild(image);
image.onload = loadImage();
}
}
else
{
iDisplay.innerHTML = "File type not supported."
}
})
}
// End File Open Code
// Begin Load Image Code - This will be used to load a preselected image
function loadImage()
{
c = document.getElementById("canvas1");
context = c.getContext("2d");
c.width = image.width;
c.height = image.height;
context.drawImage(image,0,0);
reader.readAsDataURL(file);
document.getElementById("fileInput").disabled = true;
document.getElementById("fileInputD").innerHTML = '<p>Please refresh page to open a new image</p>';
}
// End Load Image Code
But, after reviewing in the Chrome Inspector, the code never gets past
reader.onload = fileSelected;
After that line, the function exits, and nothing is loaded. I have spent hours on variations of this code and cannot get it to fire past that line. So, my question is "why?" I should note that I want to stay with pure JavaScript.
Thank you in advance.
There appears to be a bug in Chrome 73 where it isn't fired if you have a debugger statement.
I literally have
reader.readAsText(blob);
debugger;
and it never hits the onload
If I change it to
debugger;
reader.readAsText(blob);
then it works.
Fixed by Chrome 75.
You can also use FileReader.readAsDataURL() to parse the file from your . This will create a string in memory containing a base64 representation of the image.
<input type="file" accept="image/*" onchange="loadFile(event)">
<img id="output"/>
<script>
var loadFile = function(event) {
var reader = new FileReader();
reader.onload = function(){
var output = document.getElementById('output');
output.src = reader.result;
};
reader.readAsDataURL(event.target.files[0]);
};
</script>
Ref: Preview an image before it is uploaded

"canvas.toDataURL("image/png")" not working properly in firefox

I have a web page with file input field.I wanted to ,
Upload a image file.
create image element using uploaded image.
draw it on canvas
get "DataURL" of canvas.
This process works on Google Chrome,but not working on Mozilla Firefox.When i console.log the canvas.toDataURL output it shows
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABBoAAAJYCAYAAADMnIUCAAAJoUlEQVR4nO3BAQ0AAADCoPdPbQ8HFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8GeFIAAU/iP9QAAAAASUVORK5CYII=
This is not the correct output.How can i generate cross browser DataURL from the canvas.
Here is my code.
$scope.importImageForBackground = function (event)
{
$scope.file = event.target.files[0];
var img = document.createElement("img");
var reader = new FileReader();
reader.onloadend = function (e) {
$scope.$apply(function () {
img.src = e.target.result;
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 1050;
canvas.height = 600;
ctx.drawImage(img, 0, 0, 1050, 600);
$scope.data = canvas.toDataURL("image/png");
console.log($scope.data);
});
};
reader.readAsDataURL($scope.file);
};
Wait for the image to load.
img.onload = function(){
var canvas = ...
};
img.src = e.target.result;
Please note that this is a copy-n-paste of #kaiido's comment, as he refused to repost it as an answer. Credit goes to him.
I faced the same issue, You can fix this using Javascript shown as below
var canvas=document.getElementById(canvasId);
var href=canvas.toDataURL("image/png");
var windowtab=window.open('about:blank','image from canvas');
windowtab.document.write("<img src='"+href+"' alt='from canvas'/>");

Categories

Resources