Image taken from camera not saved to gallery - javascript

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!)

Related

Changing Profile Picture, and then Saving new one

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');

Need to change the javascript to link up with my button, but make the button get widgets from a RESTapi

I have a button on my html code:
<input type="button" id="myBtn" value="Next Widget" onclick="next()">
and on my javascript I have:
images = ['img/1.jpg', 'img/2.jpg', 'img/3.jpg', 'img/4.jpg', 'img/5.jpg', 'img/6.jpg', 'img/7.jpg', 'img/8.jpg', 'img/9.jpg', 'img/10.jpg'];
page = 0;
function next()
{
page++;
page %= images.length;
document.getElementById('myImg').src = images[page];
}
Also on HTML code:
<div>
<img id="myImg" width="auto" height="auto" src="img/1.jpg" alt="1">
<br>
</div>
Basically I need to change it from the saved images source to a RESTapi Url, which is sorted by id (1 to 10).
Not sure how I do this. Can anyone give me an idea.
Do I have to declare the RESTapi Url first on the javascript?
I have tried just pasted the URL in the src="My URL here". But this only shows me a broken link.
If you have direct image url you can just copy paste in your images array. If it is not the case then you will have to load your images or data first through rest api call.

Creative way to use backup image if returned image is 1x1

I'm building a reactJS app and I'm trying to retrieve the user's profile picture from their outlook account.
Reading Outlook's documentation I can use the below URL to get that photo (replacing EMAILHERE with the user's email):
https://outlook.office.com/owa/service.svc/s/GetPersonaPhoto?email=EMAILHERE&UA=0&size=HR64x64
However, if the user does NOT have a profile picture set, it will return a 1x1 image.
In my React app I want to display the user's image if it exists, if not use a generic image ({this.addDefaultSrc}). However, since even if the user does not have a profile picture set, it still returns a 1x1 image, how can I accomplish this?
Can I check to see how big the image is and if its over 1x1 then return? Since the URL does not return a error, I'm not sure what other creative ways there are to accomplish this.
Here is my current code:
<div className={styles.chatBody}>
<h6>Chat Window</h6>
{chatArray.map((item,i) =>
<div className={`${styles.answer} ${styles.left}`}>
<div className={styles.avatar}>
<img onError={this.addDefaultSrc} src="https://outlook.office.com/owa/service.svc/s/GetPersonaPhoto?email=EMAILHERE&UA=0&size=HR240x240&sc=1612564823453" alt="User name" />
</div>
<div className={styles.name}>{item.userName}</div>
<div className={styles.text}>{item.message}</div>
<div className={styles.time}>{item.time}</div>
</div>
)}
</div>
addDefaultSrc(ev){
//Code Here to check onError (not sure if it will ever be on error since returns 1X1)
ev.target.src = 'location-to-backup-image-here'
}

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

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