Changing Profile Picture, and then Saving new one - javascript

I am writing a program that has a profile page and I want to be able to switch the profile picture. I am able to change it but I am not sure how to go about saving the new picture from the files.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="profile-container">
<image id="profileImage" src="https://t3.ftcdn.net/jpg/03/46/83/96/360_F_346839683_6nAPzbhpSkIpb8pmAwufkC7c5eD7wYws.jpg" />
</div>
<input id="imageUpload" type="file" name="profile_photo" placeholder="Photo" required="" capture>
<script>
$("#profileImage").click(function(e) {
$("#imageUpload").click();
});
function fasterPreview( uploader ) {
if ( uploader.files && uploader.files[0] ){
$('#profileImage').attr('src',
window.URL.createObjectURL(uploader.files[0]) );
}
}
$("#imageUpload").change(function(){
fasterPreview( this );
});
</script>
This is my code to change the picture, but I don't know how to save the new one. Every time I refresh the page, the picture goes back to the default.

If using local storage is an option, I think it would solve your issue. I am not very comfortable in jquery but I think you are trying to change the src attribute if a new image is provided.
You could initially store the path to the image in local storage.
localstorage.setItem('imgPath', 'https://path-to-image-here');
Then, when a new image is uploaded, just change the path in local storage. You can show this image in your profile like this:
localstorage.getItem('imgPath');

Related

Image taken from camera not saved to gallery

I'm implementing a simple image upload form. When on the phone the user has the option of taking a photo with the camera and uploading it.
For some reason, the picture taken this way is not saved to the gallery.
Is there anything missing in the HTML declaration to enable the picture to be saved to gallery irregardles of whether it is discarded or used?
This is my form(in Angular):
<ng-container *ngFor="let image of imageList; let i = index;">
<div class="mb-1" fxLayoutAlign.gt-xs="space-between" fxLayoutGap.xs="10px" fxLayout.xs="column">
<input type="file" accept="image/*" [disabled]="image.hasOwnProperty('Id') && image?.Id" (change)="showPreview($event, img, i)" #input/>
<img [src]="image?.url" alt="" #img class="image-limited" />
<p *ngIf="image?.url !== ''" fxLayoutAlign.xs="center center">{{ image?.hasOwnProperty('name') ? image?.name : (form.get('AssetNumber').value || '') + '_' + (i + 1) }}</p>
<button md-raised-button color="accent" class="delete-button" (click)="clearImage(input, img, $event, i)" [disabled]="image?.url === ''">
<i class="fa fa-remove"></i> {{ 'ADD_EDIT_ASSET_IMAGE_DELETE_BUTTON_TEXT' | translate }}
</button>
</div>
<hr class="mb-1" *ngIf="i !== imageList.length - 1" />
</ng-container>
This method gets called on change of the input:
showPreview(event: { target: { files: FileList, value: string } }, element: HTMLImageElement, imageIndex: number): void {
ImageCompression.compress(event.target.files[0], this.configurationService.previewQuality)
.then((res: File) => {
const imageUrl: string = URL.createObjectURL(res);
this.imageList[imageIndex].url = this.sanitizer.bypassSecurityTrustUrl(imageUrl);
this.renderer.setAttribute(element, 'src', imageUrl);
});
}
TL;DR: Is not the expected behaviour.
When you take input a file in a web page, the user doesn't expect the image to be saved. They expect the image to be upload to the page, and maybe to the server.
An installed app has permissions and memory space assigned to it. It is expected that the app would save an image. A web page is not an App installed in the phone, it has no memory assigned and doesn't have permissions. Users will get mad if a web page suddenly starts to save images in their memory without ther permission.
Having said that, you sure can take a photo and then download it to the memory of the phone. But the user will see it as it, as a download.
But there's a problem: you don't control where the photo is coming from. The user might select the file picker and input an already saved image, if you download it without asking then the user might have duplicate files in their memory. That would drive me crazy for sure.
Asking the user if they want it to be downloaded will be better.
That behaviour ensures consistency in the page seen in a desktop or mobile. But again, you don't control where the images are going to be saved or if the images will get downloaded for sure. If you need the images for later, you need the user to select those images and input them as usually.
Referring to this article i've made some code, tested and working pretty well.
Code main function is capture function, which gets 2d context, and then pushes image to array you are iterating by in view of your component. I am pretty sure you will be able to adjust this solution to your needs :D
some code from some.component.ts looks like
public capture() {
const context = this.canvas.nativeElement.getContext('2d').drawImage(this.video.nativeElement, 0, 0, 640, 480);
this.captures.push(this.canvas.nativeElement.toDataURL('image/png'));
}
and some.component.html looks like
<div id="app">
<div><video #video id="video" width="640" height="480" autoplay></video></div>
<div><button id="snap" (click)="capture()">Snap Photo</button></div>
<canvas #canvas id="canvas" width="640" height="480"></canvas>
<ul>
<li *ngFor="let c of captures">
<img src="{{ c }}" height="50" />
</li>
</ul>
</div>
Maybe it's related with the permissions, this one allows to storage, meanwhile CAMERA one probably only allows to use it:
https://developer.android.com/reference/android/Manifest.permission#WRITE_EXTERNAL_STORAGE
What is your permissions list?
(Probably it's not related, but just in case!)

Clear form after submit image in Meteor

I’m using CFS for files upload in my Meteor App, almost everything works fine, except because when I try to upload another image, I see my previous sended image in the form, so I need to clear that form after submit the image. I've tried with .reset but it doesn't work. This is my code right now. Thanks for the help.
NewImage.html
<template name="newImage">
<div align="center">
<form align="center">
<div>
<div>
<span class="btn btn-success btn-file">
<input type="file" accept=".gif,.jpg,.png" class="myFileInputimagepub" id="image"/>
</span>
</div>
<div>
<img src="{{currentUser.profile.image}}" alt="Image" width="60px" height="60px" class="img-circle avatar-upload" value=''/>
</div>
</div>
</form>
</div>
</template>
NewImage.js
import './newImage.html';
Template.NewImage.events({
'change .myFileInputimagepub':function(evt,tmpl){
FS.Utility.eachFile(event,function(file){
fileImagespub.insert(file,function(err,fileObj){
if(!err){
var userId = Meteor.userId();
var imageurl = {
'profile.image':'/cfs/files/fileimages/' + fileObj._id
};
setTimeout(function(){
Meteor.users.update(userId,{$set:imageurl});
},2000);
}
})
})
},
'submit form':function(event,template){
event.preventDefault();
template.find("form").reset();
}
});
If the image in question is the one with class .img-circle, the issue is that its src attribute is being dynamically provided. Currently it is currentUser.profile.image. This won't clear just by resetting the form and manually clearing the image's src value would be fighting the framework.
Option 1 (Not Ideal):
If you don't want to keep the image, unset the database change made after the file upload by running something like this:
Meteor.users.update(userId, { $set: { 'profile.image': null }});
This is not ideal as it enables you to continue modifying the database with an image which may not be needed long-term.
Additionally, I'm assuming you're currently using the autopublish/insecure packages. You'll want to remove these before going public with your app as they allow any user to change the database without restriction.
Option 2:
You could save the returned value from your 'change .myFileInputimagepub' event as a ReactiveVar, then only actually run Meteor.users.update (preferably on the server using a Method) when your user submits the form. At that point you could clear the reactive variable.
Using a ReactiveVar will allow you to provide the saved URL to the src attribute via a helper, and then change the ReactiveVar's value when you wish to clear the form.
There's a simple example of manipulating ReactiveVars here: https://gist.github.com/ahoereth/a75d2d6528b1844ad503

Sails.js file upload - destroying req.body and .upload() callback executing before upload is actually complete

I am building a website using Sails, a page of which contains a form. This form has multiple text inputs, and a file upload input for the user to upload an image. The information from all text inputs are stored in a Postgres database, and the image is uploaded using the .upload() function described in the sails docs here and converted to a data uri which is then stored in the same Postgres database and used to display the image on the site.
The file input is the third to last input on the page, and I noticed that two things were happening:
1) The text in the two inputs after the file input was not being passed through to the controller as part of req.body, as form inputs normally are.
2) No data uri was stored in the database for some images.
I created a new basic sails app with a form that allows you to upload an image and exactly the same thing happens here.
Upon testing I discovered that small images work fine, while larger images do not. The 'small' image I used was 66kb, while another 800kb image produced the same effects mentioned above.
The new sails app, in the callback to the .upload() function, res.views another page that simply displays the uploaded image. With the 800kb image and larger images, by the time the page was rendered, instead of displaying the uploaded image, it displayed a broken image. In the chrome dev console it gave a 404 error for the image link, but if I add a query to the end of the image url (i.e. make chrome think it's a different url so reload the same image), the image displays fine. From this I am guessing that the .upload() callback is being called before the image is actually finished uploading, and by the time I have reloaded the image it has finished uploading.
I can see in the request headers that the inputs after the file input are being sent, but doing console.log(req.body) in the controller only logs out the inputs placed before the file input in the form.
I am using sails v0.11.0, and the code I am using is as follows:
HTML form (index.ejs)
<h1>Image Upload Test</h1>
<form method="post" enctype="multipart/form-data" action="/submit">
<div>
<input type="text" name="firstInput">
</div>
<div>
<input type="file" name="image">
</div>
<div>
<input type="text" name="imageUploaded" value="false">
</div>
<div>
<input type="hidden" name="test" value="hello!">
</div>
<button type="submit">Upload</button>
<script type="text/javascript">
$('input:file').change(function() {
$('input[name=imageUploaded]').val('true')
});
</script>
</form>
config/routes.js
module.exports.routes = {
'/': 'ImageController.show',
'/submit': 'ImageController.create'
The controller (ImageController.js)
module.exports = {
show: function(req, res) {
res.view('index.ejs');
},
create: function(req, res) {
var fileName = 'image' + Date.now() + '.jpg';
req.file('image')
.upload({saveAs: __dirname + '/../../assets/images/' + fileName}, function(err, uploadedFiles) {
if (err) return res.serverError(err);
console.log('file uploaded');
console.log();
console.log(req.body);
res.view('uploadedImage', {fileName: fileName});
});
}
};
The page to display the uploaded image (uploadedImage.ejs)
<%if (typeof(fileName) !== 'undefined') {%>
<a href="/">
<img src="/images/<%=fileName%>" style="width:100%; height:100%;">
</a>
<%}%>
Can anyone explain why this is happening and help me to fix it?
Thanks
As per sails file upload documentation, All the text fields must be uploaded before file field, otherwise they dont get passed to action.
Sails documentation File Upload sails

{"errors":["Invalid image URL"]} with aviary integration

I am doing image editing integration with Aviary.
Below is the html code
<body>
<a href="#" onclick="return launchEditor('editableimage1','http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg');">
<img id="editableimage1" src="http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg"/></a>
<br>
<form id="myform" action="" method="post">
<input id="hf" type="hidden" name="url">
<input type="submit" value="Save" />
</form>
<script type="text/javascript" src="http://feather.aviary.com/js/feather.js"></script>
<!-- Instantiate the widget -->
<script type="text/javascript">
var featherEditor = new Aviary.Feather({
apiKey: '1234567',
apiVersion: 3,
theme: 'light',
tools: ['draw','text'],
onSave: function(imageID, newURL) {
var img = document.getElementById(imageID);
img.src = newURL;
console.log('newURL '+newURL);
document.getElementById("hf").value=newURL;
featherEditor.close();
//document.forms["myform"].submit();
}
});
function launchEditor(id, src) {
featherEditor.launch({
image: id,
url: src
});
return false;
}
</script>
</body>
On opening the above html:
Image will be rendered.
On click of the image, image editing tool will open with the image in it.
But if I replace the url with any other image url say http://ipaddress:8080/ImageCheck/imgjsp.jsp which actually renders image in the browser.
Image will be rendered.
On click of the image, image editing tool opens and close immediately with the error {"errors":["Invalid image URL"]} . Tool is unable to get image into its server for editing from my UrL.
What is the difference between "http://ipaddress:8080/ImageCheck/imgjsp.jsp" and "http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg" for tool to behave differently. Any help appreciated
We are getting the same error too, I've did some searching and found this:
https://creativesdk.zendesk.com/hc/en-us/articles/202903359-Migrating-from-the-Aviary-SDK-to-the-Adobe-Creative-SDK-Beta
It looks like Aviary has updated their API
is http://ipaddress:8080/ImageCheck/imgjsp.jsp points to local ip?
according to https://creativesdk.adobe.com/docs/web/#/articles/gettingstarted/index.html, "requires that the image at the location be publicly available as our server must download it.".
On the other hand, we were able to pass base64 encoded image as a value for url parameter. This way, no need to have actual image to be stored first.
(This approach is not working for us when using hi-res version of Aviary image tool).

Image as a post variable

I am working on a site where there is a feature for users to be able to sign directly on the webpage using a canvas free form pen tool. When users click the 'apply signature' button the signature that the user drew is converted into an image and saved on the page as an <img src=""> (as you can see in the code below). Up until this point everything works great.
The problem is, When the user submits the form, I am trying to get the newly created canvas image to submit with it as a post variable and render on the process.php page as the signature that was signed. It appears that image (toDataURL()) gets passed as a post variable, but for some reason it does not render on the process.php page. It appears like the image source is not found.
I am new to javascript and I have been trying to fix this problem for days now, I would appreciate any help with fixing this. Many thanks in advance!
Markup
<div class="signature-field">
Sign:
<span class="sketch-container">
<canvas id="simple_sketch" width="350" height="100"></canvas>
</span>
Date: <input name="signature-date" type="text"><br/>
<div class="signature-buttons">
<span class="save-signature">Apply Signature | </span>
<span class="reset-canvas">| Reset Signature</span><br/>
</div>
</div>
<form method="post" action="process.php">
<input type="text" name="fname">
<input id="signature" name="signature" type="hidden">
<input type="submit">
</form>
JavaScript
$(function () {
var sktch = $('#simple_sketch').sketch();
var cleanCanvas = $('#simple_sketch')[0];
$('.save-signature').click(function () {
/* replace canvas with image */
var canvas = document.getElementById("simple_sketch");
var img = canvas.toDataURL("image/png");
$('#simple_sketch').replaceWith('<img src="' + img + '"/>');
$('.signature-buttons').replaceWith('');
document.getElementById("signature").value = $('.sketch-container').html();
});
});
I'm not quite sure what you're doing here, but if you want to post the image data through the hidden signature field, simply do this:
document.getElementById("signature").value = document.getElementById("simple_sketch").toDataURL("image/png");
As right now, it looks like you're posting the image data including <img> tags ("<img src="<DataUrl>"/>")
How about your server-side code, is the img param output empty? Are you sure the img data is being sent through the request? Try some packet sniffing tool like Fiddler or Wireshark and analyze the contents of the request (You can also take a quick look with Firebug).
Perhaps you could try some other approach to convert the img data:
https://developer.mozilla.org/en-US/docs/HTML/Canvas/Pixel_manipulation_with_canvas

Categories