I was able to follow some steps to create a canvas element from a selected image file, then create an image from that canvas element. I need to do this so the image sent to parse isnt a huge file.
Now I need to be able to access that image in the form of a file and upload through parse.
I'm a bit stuck as far as how to go about accessing the blob that's is created.
consider this:
//upload post
$('#fileselect').bind('change', function(e) {
readURL(this);
setTimeout(function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
img = new Image();
img.onload = function() {
canvas.height = canvas.width * (img.height / img.width);
/// step 1
var oc = document.createElement('canvas'),
octx = oc.getContext('2d');
oc.width = img.width * 0.5;
oc.height = img.height * 0.5;
octx.drawImage(img, 0, 0, oc.width, oc.height);
/// step 2
octx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5);
ctx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5, 0, 0, canvas.width, canvas.height);
}
img.src = $(".previewupload").attr('src');
var image2 = $('.imagereceive');
setTimeout(function() {
var canvurl = canvas.toDataURL("image/png");
image2.attr('src', canvurl);
var name = "image1.jpg"; //This does *NOT* need to be a unique name
var dataURL = canvas.toDataURL('image/jpeg', 0.5);
var blob = dataURItoBlob(dataURL);
var fd = new FormData(document.forms[0]);
fd.append("canvasImage", blob);
var file = fd;
var name = "image1.jpg"; //This does *NOT* need to be a unique name
var parseFile = new Parse.File(name, file);
$(this).attr('data-name', nameCurrent);
var imgname = $(this).attr('data-name');
$('#uploadbutton').click(function(e) {
var currentUser = Parse.User.current();
var statusupdate = $('#statusupdateform').val();
parseFile.save().then(function() {
var nameCurrent = currentUser.getUsername();
var wall = new Parse.Object("wall");
wall.set("imagefile", parseFile);
wall.save({
success: function() {
alert(parseFile.url());
},
error: function() {
alert("upload failed. please try again!");
}
});
});
});
}, 200);
}, 1000);
});
Thank you for any suggestions/help
UPDATED
solved by adding the following lines
var base64 = dataURL.split('base64,')[1];
var parseFile = new Parse.File(name, { base64: base64 });
Related
I'm trying to get random image from input video file, and then put the image into opencv to get grayScale image on the webpage.
Getting random image from video is solved by below-solution.
Javascript how to extract frame from video?
but now i'm stuck to the problem, Is it impossible to give base 64 source image file into opencv(imread, imshow, cv.cvtColor)? Please help me.
'''
//const cv = require("./js/opencv");
var video = document.createElement("video");
var image = new Image();
var canvas = document.getElementById("prevImgCanvas");
var canvas_after = document.getElementById("canvas_after");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
video.addEventListener('loadeddata', function() {
reloadRandomFrame();
}, false);
video.addEventListener('seeked', function() {
var context = canvas.getContext('2d');
context.drawImage(video, 0, 0, canvas.width, canvas.height);
const dataurl = canvas.toDataURL("image/jpeg")
image.src = dataurl;
image.onload = function(){
console.log(image);
let mat = cv.imread(image);
cv.imshow('canvasOutput', mat);
mat.delete();
};
}, false);
var playSelectedFile = function(event) {
var file = this.files[0];
var fileURL = URL.createObjectURL(file);
video.src = fileURL;
}
var input = document.getElementById('fileinput');
input.addEventListener('change', playSelectedFile, false);
function reloadRandomFrame() {
if (!isNaN(video.duration)) {
var rand = Math.round(Math.random() * video.duration * 1000) + 1;
video.currentTime = rand / 1000;
}
}
'''
let image = new Image()
image.src = 'your base64'
await new Promise(r => {
image.onload = r
})
cv.imread(image)
I tried to Html5 input capture from camera(Samsung Tab s7) and then resize(my main goal this point is reducing image size) and than upload post method via my controller. But when I upload, my file recognized .bin and save like this. Icouldnt save jpeg. How can I solve it?
HTML :
<input type="file" id="captureImageInput" style="display:none;" accept="image/*" capture>
JS :
const fileInput = document.getElementById('captureImageInput');
fileInput.addEventListener('change', e => {
if (e.target.files.length == 0) {
// No file captured, ignore
return;
}
else{
var imageFile = e.target.files[0];
//--resize image START
var canvas = document.createElement("canvas");
var img1 = document.createElement("img");
img1.setAttribute('src', imageFile);
var ctx = canvas.getContext("2d");
ctx.drawImage(img1, 0, 0);
var MAX_WIDTH = 800;
var MAX_HEIGHT = 600;
var width = img1.width;
var height = img1.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
}
else if (width == 0 && height == 0)
{
width = MAX_WIDTH;
height = MAX_HEIGHT;
}
else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img1, 0, 0, width, height);
var dataurl = canvas.toDataURL("image/jpeg");
var blobBin = atob(dataurl.split(',')[1]);
var array = [];
for (var i = 0; i < blobBin.length; i++) {
array.push(blobBin.charCodeAt(i));
}
var resizedFileBlob = new Blob([new Uint8Array(array)], { type: 'image/jpeg' });
//--resize image END
var fullFileName = serialNo + "-" + stockNo;
var fileImage = new File([resizedFileBlob], fullFileName);
var myFormData = new FormData();
myFormData.append('FormFile', fileImage);
$.ajax({
//POST OPERATION TO CONTROLLER
});
}
});
Controller side:
[HttpPost]
public JsonResult SavePhysicalPath(FileModel myFormData)
{
//update physical path operatıons..
}
FileModel class:
public class FileModel
{
public string FileFolderPath { get; set; }
public string Files { get; set; }
public IFormFile[] FormFile { get; set; }
}
According to your codes, I think the issue is related you have create a new file by using this line var fileImage = new File([resizedFileBlob], fullFileName);.
I suggest you could remove this line and directly use the resizedFileBlob as the parameter and pass to backend.
I have create a test demo as below and you could refer to it.
Js:
<script type="text/javascript">
$(document).ready(function () {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var img = new Image();
img.onload = function () {
// set size proportional to image
canvas.height = canvas.width * (img.height / img.width);
// step 1 - resize to 50%
var oc = document.createElement('canvas'),
octx = oc.getContext('2d');
oc.width = img.width * 0.5;
oc.height = img.height * 0.5;
octx.drawImage(img, 0, 0, oc.width, oc.height);
// step 2
octx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5);
// step 3, resize to final size
ctx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5,
0, 0, canvas.width, canvas.height);
}
img.src = "https://i.imgur.com/SHo6Fub.jpg";
var cav = document.getElementById("canvas");
const file = dataURLtoBlob(cav.toDataURL());
var fileImage = new File([file], "test");
const fd = new FormData;
fd.append('image', fileImage);
$.ajax({
type: 'POST',
url: '/api/Foo',
data: fd,
processData: false,
contentType: false
});
});
function dataURLtoBlob(dataURL) {
let array, binary, i, len;
binary = atob(dataURL.split(',')[1]);
array = [];
i = 0;
len = binary.length;
while (i < len) {
array.push(binary.charCodeAt(i));
i++;
}
return new Blob([new Uint8Array(array)], {
type: 'image/png'
});
};
</script>
View:
<img src="https://i.imgur.com/SHo6Fub.jpg" width="300" height="234">
<canvas id="canvas" width=300></canvas>
Result:
I am trying to upload two and more images into one canvas and make some sort of collage. Pictures are the same size. However, when I try upload the second image, the first one disappears. Below there is the code and example to JSfiddle. What is wrong?
jsfiddle
<div>
<input type="file" id="imageLoader1" name="imageLoader" />
<br/>
<input type="file" id="imageLoader2" name="imageLoader" />
<br/>
<canvas id="canvas" style="background:red;"></canvas>
</div>
And JS code:
var imageLoader1 = document.getElementById('imageLoader1');
var imageLoader2 = document.getElementById('imageLoader2');
imageLoader1.addEventListener('change', handleImage, false);
imageLoader2.addEventListener('change', handleImage, false);
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
function handleImage(e) {
if (e.target == imageLoader1) {
var reader = new FileReader();
reader.onload = function (event) {
var img1 = new Image();
img1.onload = function () {
canvas.width = 1000;
canvas.height = 500;
ctx.drawImage(img1, 0, 0, img1.width, img1.height, 0, 0, img1.width * 0.4, img1.height * 0.4);
}
img1.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
if (e.target == imageLoader2) {
var reader = new FileReader();
reader.onload = function (event) {
var img2 = new Image();
img2.onload = function () {
canvas.width = 1000;
canvas.height = 500;
ctx.drawImage(img2, 0, 0, img2.width, img2.height, img2.width * 0.4, img2.height * 0.4, img2.width * 0.4, img2.height * 0.4);
}
img2.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
}
The idea was taken here: How to upload image into HTML5 canvas
When you are trying to superimpose multiple images in single canvas,You need to use two distinct paths, also you need to clearly circumscribe them with the .beginPath() method.
I have modified you code, please check. It should work for you.
function handleImage(e) {
if (e.target == imageLoader1) {
var reader = new FileReader();
reader.onload = function (event) {
var img1 = new Image();
img1.onload = function () {
canvas.width = 1000;
canvas.height = 500;
//added begin path here
ctx.beginPath();
ctx.drawImage(img1, 0, 0, img1.width, img1.height, 0, 0, img1.width * 0.4, img1.height * 0.4);
}
img1.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
if (e.target == imageLoader2) {
var reader = new FileReader();
reader.onload = function (event) {
var img2 = new Image();
img2.onload = function () {
canvas.width = 1000;
canvas.height = 500;
//added begin path here
ctx.beginPath();
ctx.drawImage(img2, 0, 0, img2.width, img2.height, img2.width * 0.4, img2.height * 0.4, img2.width * 0.4, img2.height * 0.4);
}
img2.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
}
Alternate :
Or what you can do is use globalAlpha property of canvas.
Try : ctx.globalAlpha = 0.5; .This may solve your issue.
Alternate 2:
You can use multiple canvas layer for multiple images. This will directly superimpose your images. You can superimpose as many images as you want.
I've modified original jsfiddle: click.
Here what have been changed:
var imageLoader1 = document.getElementById('imageLoader1');
var imageLoader2 = document.getElementById('imageLoader2');
imageLoader1.addEventListener('change', handleImage, false);
imageLoader2.addEventListener('change', handleImage, false);
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
let z = 0.4; // zoom
canvas.width = 1000;
canvas.height = 500;
function handleImage(e) {
if (e.target == imageLoader1) {
let img = new Image();
img.src = URL.createObjectURL(e.target.files[0]);
img.onload = function() {
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, img.width * z, img.height * z);
}
}
if (e.target == imageLoader2) {
let img = new Image();
img.src = URL.createObjectURL(e.target.files[0]);
img.onload = function() {
ctx.drawImage(img, 0, 0, img.width, img.height, img.width * z, img.height * z, img.width * z, img.height * z);
}
}
}
I've moved canvas initialization out of load handler and simplified the loader.
This solution will not superimpose your images (but this is just a fix for original jsfiddle from the Question).
I tried everything to get this work but didn't happen.
Want a method to combine two images (that they are overlayed somehow).
I tried it like described here: Merge Image using Javascript
With this Code:
var c=document.createElement("canvas");
c.width = 100;
c.height = 100;
var ctx=c.getContext("2d");
var imageObj1 = new Image();
imageObj1.src = base64String;
var imageObj2 = new Image();
imageObj1.onload = function() {
ctx.drawImage(imageObj1, 0, 0, 328, 526);
imageObj2.src = "2.png";
imageObj2.onload = function() {
ctx.drawImage(imageObj2, 15, 85, 300, 300);
var img = c.toDataURL("image/png");
}
};
But it doesn't work.
I get the first image by Base64 from Local Storage (as described here) like this:
var img = new Image();
img.src = base64String;
And the base64 String looks like this: data:image/png;base64,iVBORw0KGgoAAAANS....
Does this somehow break this approach with canvas?
Any help is appreciated :) took me already hours and can't figure it out....
Fixed it like this:
var c = document.createElement('canvas');
c.width = 82;
c.height = 75;
var ctx = c.getContext("2d");
var imageObj2 = new Image();
imageObj2.onload = function (){
ctx.drawImage(imageObj2, 0, 0, 82, 75);
var imageObj1 = new Image();
imageObj1.onload = function (){
imageObj1.style.objectFit = "cover";
ctx.drawImage(imageObj1, 14, 4, 53, 53);
};
imageObj1.src = data.elephant;
};
imageObj2.src = "2.png";
/**
* Converts data URI in 'image/png' format to an image data object
* #param dataURL Base64 encoded string
* #returns {ImageData/undefined}
*/
convertDataURLToImageData: function (dataURL) {
if (dataURL !== undefined && dataURL !== null) {
var canvas, context, image, imageData;
canvas = document.createElement('canvas');
canvas.width = 470;
canvas.height = 470;
context = canvas.getContext('2d');
image = new Image();
image.addEventListener('load', function(){
context.drawImage(image, 0, 0, canvas.width, canvas.height);
imageData = context.getImageData(0, 0, canvas.width, canvas.height);
//how do i return this?
}, false);
image.src = dataURL;
return imageData;
}
}
considering the snippet above, if I would like to get an array of image data from a data URL I wold draw it on a canvas , how do I return the image data?
The problem is that your function is asynchronous, because you are waiting for the load event.
Then, you could use promises:
function convertURIToImageData(URI) {
return new Promise(function(resolve, reject) {
if (URI == null) return reject();
var canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
image = new Image();
image.addEventListener('load', function() {
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0, canvas.width, canvas.height);
resolve(context.getImageData(0, 0, canvas.width, canvas.height));
}, false);
image.src = URI;
});
}
var URI = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAABMLAAATCwAAAAAAAAAAAABsiqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/iKC3/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/2uLp///////R2uP/dZGs/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/////////////////+3w9P+IoLf/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv///////////+3w9P+tvc3/dZGs/2yKpv9siqb/bIqm/2yKpv9siqb/TZbB/02Wwf9NlsH/TZbB/02Wwf9NlsH////////////0+Pv/erDR/02Wwf9NlsH/TZbB/02Wwf9NlsH/TZbB/02Wwf9NlsH/TZbB/02Wwf9NlsH/TZbB//////////////////////96sNH/TZbB/02Wwf9NlsH/TZbB/02Wwf9NlsH/TZbB/02Wwf9NlsH/TZbB/02Wwf////////////////+Ft9T/TZbB/02Wwf9NlsH/TZbB/02Wwf9NlsH/E4zV/xOM1f8TjNX/E4zV/yKT2P/T6ff/////////////////4fH6/z+i3f8TjNX/E4zV/xOM1f8TjNX/E4zV/xOM1f8TjNX/E4zV/xOM1f+m1O/////////////////////////////w+Pz/IpPY/xOM1f8TjNX/E4zV/xOM1f8TjNX/E4zV/xOM1f8TjNX////////////T6ff/Tqng/6bU7////////////3u/5/8TjNX/E4zV/xOM1f8TjNX/AIv//wCL//8Ai///AIv/////////////gMX//wCL//8gmv////////////+Axf//AIv//wCL//8Ai///AIv//wCL//8Ai///AIv//wCL///v+P///////+/4//+Axf//z+n/////////////YLf//wCL//8Ai///AIv//wCL//8Ai///AIv//wCL//8Ai///gMX/////////////////////////////z+n//wCL//8Ai///AIv//wCL//8Ai///AHr//wB6//8Aev//AHr//wB6//+Avf//7/f/////////////v97//xCC//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";
convertURIToImageData(URI).then(function(imageData) {
// Here you can use imageData
console.log(imageData);
});
var img = new Image;
img.src = strDataURI;
try this hope u will understand ..