compressing and saving image captured to localStorage - javascript

I'm working on an HTML widget which will be embedded in an iBook in iBooks Author for the iPad.
I've got a simple button to trigger image capture on an iPad and all is working fine.
<div id="zeroDiv">
<input type="file" id="getPic" accept="image/*">
</div>
<div id="picWrapper">
<img id="image">
<div id="buttDiv">
<button id="picButt"><span class="buttText">Insert image</span>
</button>
</div>
</div>
and
$('#picButt').click(function () {
$('#getPic').trigger('click');
});
$(document).ready(function () {
$("#getPic").on("change", gotPic);
$("#image").load();
});
function gotPic(event) {
$("#image").attr("src", URL.createObjectURL(event.target.files[0]));
$("#picButt span").text("Change image");
}
fiddle at https://jsfiddle.net/mikawaben/cq2yrh2z/
However, when the user moves off a page and returns, the image is lost as the page reloads. I need to store the image in localStorage.
I know that the fiddle at http://jsfiddle.net/VXdkC/2/ (courtesy of Musa on this site) holds code which could be the key for me.
$('#addNote').click(function () {
var Title = $('#title').val();
var Message = $('#message').val();
var pic = document.getElementById("file").files[0];
var imgUrl;
var reader = new FileReader();
reader.onload = function(e) {
var imgURL = reader.result;
$('#notes').prepend("<div class='entry'><h1>" + Title + "</h1></p>"+ "<p>" + Message + "<img src=" + imgURL + "></p> </div>");
var notes = $('#notes').html();
localStorage.setItem('notes', notes);
saveDataToLocalStorage(imgURL);
}
reader.readAsDataURL(pic);
return false;
});
//show content of notes in storage
$('#notes').html(localStorage.getItem('notes'));
return false;
But despite messing around with it for a couple of hours, I'm not getting it to work. Can anyone lend a hand with this?
I'm also concerned about compression. Do I need to use base64 encoding or something in case the image size causes the whole thing to crash?

Just check to see if there is an imaged saved on page load and display it. Then save the image when selected.
$(document).ready(function () {
$("#getPic").on("change", gotPic);
if (localStorage['url']){
$("#image").attr("src", localStorage['url']);
$("#picButt span").text("Change image");
}
});
function gotPic(event) {
var reader = new FileReader();
reader.onload = function(){
$("#image").attr("src", this.result);
localStorage['url'] = this.result;
$("#picButt span").text("Change image");
}
reader.readAsDataURL(event.target.files[0]);
}
https://jsfiddle.net/cq2yrh2z/1/

Related

Save <img> to File Share using AJAX

I am trying to somehow save my image generated with <input type="file" id="file_capture" capture="user" accept="image/*"/> through vb.net ajax and save the file into a file share folder.
I need image capture so that if the user is on their phone it will screen capture.
I have tried jquery-webcame with no luck and have ended with only HTML Capture working up to the point when I need to save the file.
So far the image src looks something like this data:image/jpeg;base64,/...
When I pass the src into ajax I tried to read it using Net.WebClient but I am unsure how to get the address of the img when all I have is the src value to use for My.Computer.Network.DownloadFile
VB.NET
<System.Web.Services.WebMethod(EnableSession:=True)> Public Shared Function SaveImage(ByVal src As String) As String
Try
Dim client As Net.WebClient = New Net.WebClient
Dim destination = "\\serverName\FolderShareName\"
client.DownloadFile(src, destination)
Catch ex As Exception
End Try
Return "Pass"
End Function
HTML
<label class="cameraButton" style="min-width:150px;">Capture File
<input type="file" id="file_capture" capture="user" accept="image/*"/>
</label>
<div id="imageHolder" class="col-sm-12" style="border:1px solid red;text-align:center;min-width:150px;" runat="server">
</div>
JAVASCIRPT [I created it this way so multiple images can be uploaded]
$('#file_capture').change(function () {
AddNewImage(this);
});
function AddNewImage(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
var id = $("#imageHolder > div > img").length
var fullid = "uploadImage" + id++;
var DIV = document.createElement("DIV");
DIV.className = "imgWrap"
DIV.ID = "imgWrapID" + id++;
DIV.style.display = "inline-block";
DIV.style.padding = "10px";
document.getElementById('imageHolder').appendChild(DIV);
var img = new Image(200, 200);
reader.onload = function (e) {
img.src = e.target.result;
img.id = fullid
}
reader.readAsDataURL(input.files[0]);
var btn = document.createElement("BUTTON");
btn.innerHTML = "x";
btn.className = 'top-right';
btn.name = DIV.ID
btn.title = fullid
btn.onclick = function () {
$("#" + this.name).remove();
$("#" + this.title).remove();
$(this).remove();
return false;
};
DIV.appendChild(btn);
DIV.appendChild(img);
}
}
client.DownloadFile(src, destination)
clearly won't accept the 64bit src value of the image so I need to somehow convert it to a address.

Javascript IDs into variables onchange

My html form works perfectly and the javascript works perfectly...the only issue is I obviously don't want to repeat the code 15 times so I need the id's to be pulled into variables.
Simply trying to get three id's from whichever form is submitted onchange. my_btn_id, my_img_id, my_input_id. That's it. I've tried thousands of possible syntax variations, looked up hundreds of answers in here and nothing has not worked the way I need it to. I'm obviously missing something. All help is appreciated.
Here is the simplified html form:
<form action="#” method=" post " id=”my_form_id”>
<input type="file " id="my_input_id "><br>
<button type="submit " value="Upload " id="my_btn_id ">Upload</button>
</form>
Here is javascript - the id's i'm looking for are highlighted with **
$(document).on('change', '.btn-file :file', function () {
var input = $(this),
label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
input.trigger('fileselect', [label]);
});
$('.btn-file :file').on('fileselect', function (event, label) {
var input = $(this).parents('.input-group').find(':text'),
log = label;
if (input.length) {
input.val(log);
} else {
if (log) alert(log);
}
});
function readURL(input) {
**var imgid = "#my_img_id";**
**var btnid = "#my_btn_id";**
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$(imgid).attr('src', e.target.result);
$(btnid).show();
}
reader.readAsDataURL(input.files[0]);
}
}
**var inputid = "#my_input_id";**
$(inputid).change(function () {
readURL(this);
});
$(this.form) will return the form that contains the input element that the event was triggered on. You can then use this to find the other elements you want.
var form = $(input.form);
var img = form.next("img");
var btn = form.find("input:submit");
There's no need to get their IDs, you can just use the jQuery objects themselves. E.g.
img.attr("src", e.target.result);
btn.show();
Full code:
function readURL(input) {
var form = $(input.form);
var img = form.next("img");
var btn = form.find("input:submit");
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
img.attr('src', e.target.result);
btn.show();
}
reader.readAsDataURL(input.files[0]);
}
}
$("input[type=file]").change(function() {
readURL(this);
});
Many ways to do this.
$("#my_input_id1, #my_input_id2, #my_input_id3").on("change",function(){
var inputItem = $(this);
readURL(inputItem);
});
You can also create variables. For example:
<input type="file" class="inputItem" data-img="my_img_id1" data-btn="my_btn_id1">
<input type="file" class="inputItem" data-img="my_img_id2" data-btn="my_btn_id2">
<input type="file" class="inputItem" data-img="my_img_id3" data-btn="my_btn_id2">
Then with jQuery
$(".inputItem").on("change",function(){
var imgid = $(this).attr("data-img");
var btnid = $(this).attr("data-btn");
// then you can create dynamic selectors
// ...
$("#"+imgid).attr('src', e.target.result);
$("#"+btnid).show();
});
I hope this helps or point you to the right direction!

Display image from a given url

I have an array with 3 cells.At the first cell i have a textarea where you can insert the url of an image.At the second cell i have a button which when you click the image display at the third cell where i have a div to display the image.The question is how can i display the image either from the internet either from local?
The code i wrote is:
function loadImage(){
var mydiv = document.getElementById("idofdivtodisplayimg");
var url = document.getElementById("idoftextareawhereyouputtheurl");
mydiv.innerHTML = url.value;
}
<html>
<body>
<input type="text" id="imagename" value="" />
<input type="button" id="btn" value="GO" />
<script type="text/javascript">
document.getElementById('btn').onclick = function() {
img = document.createElement('img');
img.src = document.getElementById('imagename').value;
document.body.appendChild(img);
}
</script>
</body>
</html>
You can see the sample code will add the images from an array to the document.
You could also append the images to any of the elements in your function by using url.appendChild
var arr = ['http://via.placeholder.com/350x150', 'http://via.placeholder.com/350x250','http://via.placeholder.com/350x350']; // hold image urls in an array.
arr.forEach(function(item){
// loop through array and add images to the document.
var img = new Image();
img.src = item;
document.body.appendChild(img);
});
In order to do both you would need to change your html and code.
For the case when the user has a url you can just create a new image and append it to your div setting the image's src to the url that was set in the input:
function loadImage(){
var mydiv = document.getElementById("idofdivtodisplayimg");
var url = document.getElementById("idoftextareawhereyouputtheurl");
var image = new Image;
mydiv.appendChild(image);
image.src = url.value;
}
Now to get it to display a local image you will need a file input or a drag and drop scheme as you cannot access local files without some type of user interaction.
So you would, for example, need to change your html to include a file input, and grab a reference to the selected file the user selects. Then use FileReader to read the file, and finally display it
HTML
<input type="file" id="imagefile">
JS
//input reference
var imageinput = document.getElementById("imagefile");
imageinput.addEventListener('change',function (){
var mydiv = document.getElementById("idofdivtodisplayimg");
var image = new Image;
mydiv.appendChild(image);
//FileReader instance
var reader = new FileReader;
reader.addEventListener('load',function(){
//reader.result will contain a dataURL that can be used
//like a regular image url
image.src = reader.result;
});
//read the file as a dataURL
reader.readAsDataURL( imageinput.files[0] );
});
This does both, it let's you upload an image (or at least load it to the browser) or give a URL to an image source. Click the button and the image is loaded and displayed!
This snippet uses the FileReader API to get the uploaded image and display it in an image element
function uploadOrNot() {
if (document.querySelector("input[type=file]").files[0]){
let input = document.querySelector("input[type=file]");
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
display(e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
} else if (document.querySelector("input[type=text]").value){
display(document.querySelector("input[type=text]").value);
}
}
function display(res) {
let img = document.createElement("IMG");
img.src=res;
document.querySelector("#result").appendChild(img);
}
<div id="urlOrUpload">
<input type="text"/>
<br>
<input type="file" accetp="image/*"/>
</div>
<div id="buttonHolder">
<button type="button" onclick="uploadOrNot()">Display</button>
</div>
<div id="result"></div>
I partly solved it by replacing the div at the third cell with an img tag and at the function i wrote above, i chenged it to:
var image = document.getElementbyId("imageid");
var url = document.getElementbyId("urlid");
image.src = url.value;
But at the table i have,i also have a button where you can add a same row as above.How can i do this function for every url that is placed at every textbox?

How to prevent uploaded image from getting deleted when editing a form?

I'm working on an app that allows users to post events. I'm using NodeJS, Express and Mongo.
I created a form that allows users to input event details, and upload an image relating to the event. I also created a form that allows the user to edit event details.
The form looks as follows:
The Problem:
User fills form with event details and attaches a picture.
User submits form
User decides he wants to change the event title, but NOTHING ELSE
User clicks edit event, changes the title, and submits
The problem: Even though the user didn't delete the picture associated with the event, the picture is no longer there.
Here is part of my new.ejs file (for posting new event, just adding this here for reference)
<script type="text/javascript" src="/js/eventform.js"></script>
<form action="/events"
method="POST"
enctype="multipart/form-data"
onSubmit="return(validate(this));" // validating user input
novalidate >
....
....
<input name="image" type="file" id="image" accept="image/*" style="display:none" onchange="handleFiles(this.files)">
<div id="imageBorder" >
<div id="imageContainer">
<div id="dropbox">
<i class="fa fa-picture-o" aria-hidden="true"></i>
<p> Drop image here or click to upload</p>
</div>
<div id="preview" class="hidden">
</div>
<button id="fileSelect" class="...">Upload Image</button>
<button id="fileRemove" class="...">Remove Image</button>
</div>
</div>
....
....
</form>
Notice that I'm using a hidden input field. Also I have two divs, preview (hidden initially) and dropbox. When an image is uploaded, the class 'hidden' is removed from preview and added to dropbox.
Here is part of the js file newevent.js
$(document).ready(function() {
....
eventImageSetup();
....
}
....
function eventImageSetup() {
var dropbox = document.getElementById("dropbox"),
fileElem = document.getElementById("image"),
fileSelect = document.getElementById("fileSelect"),
fileRemove = document.getElementById("fileRemove");
$(dropbox).height($('#imageBorder').height());
fileSelect.addEventListener("click", function(e) {
if (fileElem) {
fileElem.click();
e.preventDefault(); // to prevent submit
}
}, false);
fileRemove.addEventListener("click", function(e) {
e.preventDefault(); // prevent submit
if(!$('#preview').hasClass('hidden')) { // if there is an image
$('#preview').empty();
$('#dropbox').removeClass('hidden');
$('#preview').addClass('hidden');
$('#fileSelect').text('Upload Image');
$('#image').wrap('<form>').closest('form').get(0).reset();
$('#image').unwrap();
}
removeError($('#imageError'), $('#image'));
});
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);
}
function handleFiles(files) {
var file = files[0];
.... // some error checking
var img = document.createElement("img");
img.id = "uploadedImage";
img.file = file;
img.onload = function() {
adjustImageSize(img);
};
$('#dropbox').addClass('hidden');
$('#preview').removeClass('hidden');
$('#preview').empty();
$('#preview').append(img);
$('#fileSelect').text('Replace Image');
var reader = new FileReader();
reader.onload = (function(aImg) {
return function(e) {
aImg.src = e.target.result;
};
})(img);
reader.readAsDataURL(file);
}
Here is part of my edit.ejs file
<form action="/events/<%=event._id%>?_method=PUT"
method="POST"
enctype="multipart/form-data"
onSubmit="return(validate(this));"
novalidate >
<input name="image" type="file" id="image" accept="image/*" style="display:none" onchange="handleFiles(this.files)">
<div id="imageBorder" >
<div id="imageContainer">
<div id="dropbox" class="hidden">
<i class="fa fa-picture-o" aria-hidden="true"></i>
<p> Drop image here or click to upload</p>
</div>
<div id="preview">
<script>
var imageExists = '<%=event.image%>';
if(imageExists) {
var myImg = document.createElement("IMG");
var source = "../../<%= event.image %>";
myImg.src = source;
adjustImageSize(myImg);
$('#preview').append(myImg);
}
</script>
</div>
<button id="fileSelect" class="...">Upload Image</button>
<button id="fileRemove" class="...">Remove Image</button>
</div>
</div> <!-- END OF imageBorder -->
....
</form>
The script above succesfully makes the image appear in the edit page, as follows.
But when you click submit, the picture doesn't show up.
Here is the nodejs route file. You can see the problem here
// UPDATE SPECIFIC EVENT IN DATABASE
router.put("/:id", upload.single('image'), middleware.checkEventOwnership, function(req, res) {
var filepath = undefined;
if(req.file) {
filepath = req.file.path.substr(7); // Substr to remove "/public"
}
req.body.image = filepath;
Event.findByIdAndUpdate(req.params.id, req.body, function(err, foundEvent) {
if(err) {
console.log(err);
req.flash("error", err);
} else {
req.flash("success", "Successfully edited your event");
}
res.redirect("/events/" + req.params.id);
});
});
Basically, if I leave the image untouched in the edit form, req.file doesn't exist. Thus, req.body.image = undefined. And an image is no longer associated with the event.
Common sense would say do this
if(req.file) {
filepath = req.file.path.substr(7);
req.body.image = filepath;
}
But if you do that, you introduce a new problem: If the user edits the event and removes the image (i.e decides he doesn't want an image associated with the event), the image never gets deleted.
Any idea how to solve this problem? I know I have to do something in the edit.ejs script... More specifically, I need to create an image file... But I'm not sure how to approach this
So I got this to work through a hack I REALLY don't like. I'm sure there is a better, cleaner, standard way of dealing with edit.ejs and images. In other words, please help me find a better solution!
Here are the changes in edit.ejs
<form action="/events/<%=event._id%>?_method=PUT"
method="POST"
enctype="multipart/form-data"
onSubmit="return validate(this) & editPageImageProcessing(this);"
novalidate >
....
....
<div id="preview">
<script>
var imageExists = '<%=event.image%>';
if(imageExists) {
var myImg = document.createElement("IMG");
var source = "../../<%= event.image %>";
myImg.src = source;
myImg.name = "previewImage";
myImg.id = "previewImage";
adjustImageSize(myImg);
$('#preview').append(myImg);
}
</script>
</div>
Basically, I added the lines
myImg.name = "previewImage";
myImg.id = "previewImage";
and added a function editPageImageProcessing.
What this function does is: IF the user didn't upload a new image, and did not delete the image, create a hidden input field "hiddenImage", and let its value be the source of the original image. See below:
// This function deals with edit image
function editPageImageProcessing(form) {
// If the user didn't change the image
// preview would be NOT hidden
// there would not be a req.file (document.getElementById('image').val == '')
// we want a hiddenimage input field
var aFile = document.getElementById('image').value;
console.log("File: ", aFile);
var preview = document.getElementById('preview');
console.log("Preview has hidden class: " + $(preview).hasClass('hidden'));
if(aFile == '' && !$(preview).hasClass('hidden')) {
var input = document.createElement('input');
$(input).attr("name", "hiddenImage");
$(input).attr("id", "hiddenImage");
$(input).attr("type", "hidden");
var myImage = document.getElementById('previewImage');
$(input).attr("value", myImage.src);
$('form').append(input);
}
return true;
}
Now, in the edit route, I did this
// UPDATE SPECIFIC EVENT IN DATABASE
router.put("/:id", upload.single('image'), middleware.checkEventOwnership, function(req, res) {
var filepath = undefined;
if(req.file) { // If user uploaded a new image
filepath = req.file.path.substr(7); // Substr to remove "/public"
console.log(filepath);
} else if(req.body.hiddenImage) { // If user kept the same image
var index = req.body.hiddenImage.lastIndexOf("/uploads");
filepath = req.body.hiddenImage.substr(index);
// req.body.hiddenImage WILL ONLY EXIST if user left image unchanged
}
req.body.image = filepath; // If user deleted image, this will be undefined, which is what we want
Event.findByIdAndUpdate(req.params.id, req.body, function(err, foundEvent) {
if(err) {
console.log(err);
req.flash("error", err);
} else {
req.flash("success", "Successfully edited your event");
}
res.redirect("/events/" + req.params.id);
});
});
Okay, so its messy.
Any better solution would be appreciated

Preview image HTML & JavaScript

I am working on an image uploader and I am currently trying to build up an image preview before the upload is done. I have this HTML code:
<input type="file" id="id_imatgeNewPeces"></input><br></br>
<img id="previewing" src="" />
Then I add a listener to the input like this:
document.getElementById('id_imatgeNewPeces').addEventListener('change', this.handleFileSelect, false);
And finally the function handleFileSelect:
handleFileSelect: function(oEvent) {
var file = oEvent.target.files[0];
if (!file.type.match('image.*')) {
sap.m.MessageToast.show("El archivo seleccionado no es una Imagen");
} else {
var readerURL = new FileReader();
readerURL.onload = function() {
$('#previewing').attr('src', readerURL.result);
$('#previewing').attr('width', '250px');
$('#previewing').attr('height', '230px');
return true;
};
readerURL.readAsDataURL(file);
}
},
I don't know why when I select a file which is not an image it displays the message but when I do select an image when the method onload ends no image is displayed and in addition it seems that the listener has been lost because no further calls are done when if I select another image.
The funny thing is that if I place a breakpoint on line '$('#previewing').attr('height', '230px');' I can see the image but when I continue it disappears. In addition when the method onload ends the fileinput "resets" I mean that it says that it has no selected files.
Besides being a old question, I've found that your code is working as expected:
I just don't undestand why use a native addEventListener() when you are using jquery for DOM manipulation, being easily replaced by:
$("#id_imatgeNewPeces").change(handleFileSelect);
var handleFileSelect = function(oEvent) {
var file = oEvent.target.files[0];
if (!file.type.match('image.*')) {
console.log("El archivo seleccionado no es una Imagen");
} else {
var readerURL = new FileReader();
readerURL.onload = function() {
$('#previewing').attr('src', readerURL.result);
$('#previewing').attr('width', '250px');
$('#previewing').attr('height', '230px');
return true;
};
readerURL.readAsDataURL(file);
}
};
$("#id_imatgeNewPeces").change(handleFileSelect);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="id_imatgeNewPeces">
<br/><br/>
<img id="previewing" src="" />

Categories

Resources