I have an issue with phonegap and iOS 9, this was working fine with ios 8, When you click on the file input it shows a cancel button in the middle of the screen that does nothing when tapped. The file input works fine in safari but in my built app, it doesn't.
I realize that there is a phonegap file uploader API, but I am using my app as a web browser to the mobile version of my website, so I haven't built a fully native app, this was a quick solution for me.
This could be because of the new action sheet style or the new option added to the action sheet in ios 9.
Does anyone have a solution that I can skip the action sheet and when clicking the input file I go directly to the camera roll? Or any fix for this?
I moved to the plugin - cordova-plugin-camera and this solved the problem.
After click on input type file:
e.preventDefault();
navigator.notification.confirm(
'Please select image', // message
function (buttonIndex) {
if (buttonIndex === 1) {
photoFromSource(navigator.camera.PictureSourceType.CAMERA);
} else {
photoFromSource(navigator.camera.PictureSourceType.PHOTOLIBRARY);
}
}, // callback to invoke with index of button pressed
'Image capture', // title
['Camera', 'Gallery'] // buttonLabels
);
function photoFromSource(source) {
var targetWidth = 640,
targetHeight = 640,
onSuccess = function (imageURI) {
var image = new Image(),
canvas = document.createElement('canvas'),
canvasContext = canvas.getContext('2d');
image.onload = function () {
canvas.width = image.width;
canvas.height = image.height;
canvasContext.drawImage(image, 0, 0, image.width, image.height);
var dataURL = canvas.toDataURL();
self.model.set('imageData', dataURL);
self.model.setDataAttr('image', true);
self.render();
};
image.src = imageURI;
},
onFail = function (message) {
// Ignore if no image seleted
if (!/^no image selected$/.test(message))
alert('Failed because: ' + message);
},
opts = {
quality: 50,
destinationType: navigator.camera.DestinationType.FILE_URI,
sourceType: source,
mediaType: navigator.camera.MediaType.PICTURE,
targetWidth: targetWidth,
targetHeight: targetHeight,
encodingType: navigator.camera.EncodingType.JPEG,
correctOrientation: true,
cameraDirection: navigator.camera.Direction.BACK,
saveToPhotoAlbum: false
};
try {
navigator.camera.getPicture(onSuccess, onFail, opts);
}
catch (e) {
alert('Could not capture image: ' + e);
}
};
Related
my image is 800 x 600px, I need to crop this pic in the midlle (600 x 600px)
I create this code but is not working
function takeSnapshot(){
// Here we're using a trick that involves a hidden canvas element.
var hidden_canvas = document.querySelector('canvas'),
context = hidden_canvas.getContext('2d');
// Make a copy of the current frame in the video on the canvas.
context.drawImage(video, 100, 0, 600, 600);
// Turn the canvas image into a dataURL that can be used as a src for our photo.
return hidden_canvas.toDataURL('image/png');
}
this is my full code
document.addEventListener('DOMContentLoaded', function () {
// References to all the element we will need.
var video = document.querySelector('#camera-stream'),
image = document.querySelector('#snap'),
start_camera = document.querySelector('#start-camera'),
controls = document.querySelector('.controls'),
take_photo_btn = document.querySelector('#take-photo'),
delete_photo_btn = document.querySelector('#delete-photo'),
download_photo_btn = document.querySelector('#download-photo'),
error_message = document.querySelector('#error-message');
// The getUserMedia interface is used for handling camera input.
// Some browsers need a prefix so here we're covering all the options
navigator.getMedia = ( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
if(!navigator.getMedia){
displayErrorMessage("Your browser doesn't have support for the navigator.getUserMedia interface.");
}
else{
// Request the camera.
navigator.getMedia(
{
video: true
},
// Success Callback
function(stream){
// Create an object URL for the video stream and
// set it as src of our HTLM video element.
video.srcObject=stream;
// Play the video element to start the stream.
video.play();
video.onplay = function() {
showVideo();
};
},
// Error Callback
function(err){
displayErrorMessage("There was an error with accessing the camera stream: " + err.name, err);
}
);
}
// Mobile browsers cannot play video without user input,
// so here we're using a button to start it manually.
start_camera.addEventListener("click", function(e){
e.preventDefault();
// Start video playback manually.
video.play();
showVideo();
});
take_photo_btn.addEventListener("click", function(e){
e.preventDefault();
var snap = takeSnapshot();
// Show image.
image.setAttribute('src', snap);
image.classList.add("visible");
// Enable delete and save buttons
delete_photo_btn.classList.remove("disabled");
download_photo_btn.classList.remove("disabled");
// Set the href attribute of the download button to the snap url.
download_photo_btn.href = snap;
// Pause video playback of stream.
video.pause();
});
delete_photo_btn.addEventListener("click", function(e){
e.preventDefault();
// Hide image.
image.setAttribute('src', "");
image.classList.remove("visible");
// Disable delete and save buttons
delete_photo_btn.classList.add("disabled");
download_photo_btn.classList.add("disabled");
// Resume playback of stream.
video.play();
});
function showVideo(){
// Display the video stream and the controls.
hideUI();
video.classList.add("visible");
controls.classList.add("visible");
}
function takeSnapshot(){
// Here we're using a trick that involves a hidden canvas element.
var hidden_canvas = document.querySelector('canvas'),
context = hidden_canvas.getContext('2d');
// Make a copy of the current frame in the video on the canvas.
context.drawImage(video, 100, 0, 600, 600);
// Turn the canvas image into a dataURL that can be used as a src for our photo.
return hidden_canvas.toDataURL('image/png');
}
function displayErrorMessage(error_msg, error){
error = error || "";
if(error){
console.error(error);
}
error_message.innerText = error_msg;
hideUI();
error_message.classList.add("visible");
}
function hideUI(){
// Helper function for clearing the app UI.
controls.classList.remove("visible");
start_camera.classList.remove("visible");
video.classList.remove("visible");
snap.classList.remove("visible");
error_message.classList.remove("visible");
}
});
To crop try...
var imgData = context.getImageData(100, 0, 600, 600); // start from 100px and a width of 600px
context.putImageData(imgData, 0, 0); // or place it back at X=100px, its up to you.
Btw, your URL returned should be...
For PNG:
URL=hidden_canvas.toDataURL('image/png').replace('image/png','image/octet-stream');
For JPG:
URL=hidden_canvas.toDataURL("image/jpeg",1.0);
It doesn't change anything manu, cropping is simple...
var Data=context.getImageData(100, 0, canvas.width-100,canvas.height); // grab the portion you want
context.clearRect(0,0,canvas.width,canvas.height); // clear the old image so the crop shows better
context.putImageData(Data,0,0); // paste it in
I think this should work for you:
let data = context.getImageData(100, 0, canvas.width / 2, canvas.height);
context.clearRect(0, 0, canvas.width, canvas.height);
context.putImageData(data, 0, 0);
I am using the awesome jquery-cropper plugin from fengyuanchen.
I'm having the issue of when certain images get uploaded it rotates and it is not on the right side which I have to make the user rotate them. I will upload the image via ajax. I'm getting the error rotate is not defined which I have been stuck a couple of hours.
$('#profilePhoto').on( 'change', function(){
if (this.files && this.files[0]) {
if ( this.files[0].type.match(/^image\//) ) {
var reader = new FileReader();
reader.onload = function(evt) {
var img = new Image();
img.onload = function() {
$("#profileImageContainer").hide();
$("#rotateImg").show();
context.canvas.height = img.height;
context.canvas.width = img.width;
context.drawImage(img, 0, 0);
cropper = canvas.cropper({
aspectRatio: 1 / 1,
rotatable: true,
});
$('#btnCrop').click(function() {
// Get a string base 64 data url
var croppedImageDataURL = canvas.cropper('getCroppedCanvas').toDataURL("image/png");
});
$('#rotateImg').click(function () {
cropper.cropper.rotate(90);
});
};
img.src = evt.target.result;
};
reader.readAsDataURL(this.files[0]);
}
else {
alert("Invalid file type! Please select an image file.");
}
}
else {
alert('No file(s) selected.');
}
});
The main problem here is about scopes since it looks like it is not reconizing the cropper variable.
This problems surfaces because when the user upload a photo sometimes this photo rotate automatically. If I could solve this problem first without having to make the user rotate the image would be better
Really stupid mistake. Instead of:
cropper.cropper().rotate(90);
I should apply:
cropper.cropper('rotate', 90);
In my app I have a functionality of clicking an image from camera plugin and then navigate to a different view and show the image there. I am saving the dataurl of the image in localStorage and then in the other view I am calling the getItem method to get the dataurl of the image clicked. After that I am assigning this dataurl to src of the image to be shown in the view. But the problem is that the image is not showing!!
I checked the localstorage while debugging, the dataurl is there under localStorage.
What can be the problem, and how to solve it ??
Controller for initiating the camera...
init_camera: function() {
var controller = this;
navigator.camera.getPicture(onSuccess, onFail, {
quality: 80,
destinationType: Camera.DestinationType.DATA_URL
});
function onSuccess(imageData) {
var image = document.getElementById('myImage');
image.src = "data:image/jpeg;base64," + imageData;
localStorage.setItem('initial', image.src);
controller.redirectTo('Preview');
}
function onFail(message) {
alert('Failed because: ' + message);
}
}
Code to get the dataurl in the other view.. (in ExtJS)
items: [{
xtype: 'image',
cls: 'prev_img',
src: localStorage.getItem('initial'),
flex: 2
},
In my application I'm using html2canvas for converting a HTML in to canvas and after that i'm converting that canvas to image using toDataURL() every thing fine in chrome the image is downloading soon after the page loads, but in safari the image loading in a the same page without downloading.
$(document).ready(function(e) {
html2canvas(document.body, {
onrendered: function(canvas) {
var test = document.getElementsByClassName('test'); //finding the div.test in the page
$(test).append(canvas); //appending the canvas to the div
var canvas = document.getElementsByTagName('canvas');
$(canvas).attr('id','test'); //assigning an id to the canvas
var can2 = document.getElementById("test");
var dataURL = can2.toDataURL("image/png");
document.getElementById("image_test").src = dataURL; //assigning the url to the image
$(canvas).remove(); //removing the canvas from the page
download(can2,'untitled.png');
function download(canvas_name,filename)
{
var tempLink = document.createElement('a');
e;
tempLink.download = filename;
tempLink.href = dataURL;
if (document.createEvent) // create a "fake" click-event to trigger the download
{
e = document.createEvent("MouseEvents");
e.initMouseEvent("click", true, true, window,0, 0, 0, 0, 0, false, false, false,false, 0, null);
tempLink.dispatchEvent(e);
}
else if (tempLink.fireEvent)
{
tempLink.fireEvent("onclick");
}
}
},logging:true,background: "#fff",
});
});
Can anybody help me what i nee to change to download the file in Safari?
iOS limitations
The iOS there are limitations which prevent direct download (practically almost all formats), where images can be downloaded holding the "touch".
The best alternative to this would be to open an "alert" with instructions and after the alert to close call "window.open" with the image.
See the code with an alternative to "iOS"
BUG in Safari (PC and MAC - non iOS - is no problem in webkit technology, but in the browser)
I tried append anchor, create "ghost-iframe" and replace mimetype: application/download.
Download manager open, but not add file after click in "Save" or "Open".
In my opinion this is a BUG in Browser (not is an issue of Webkit, the issue is of Safari).
See code:
$(document).ready(function(e) {
var ghostFrame = document.createElement("iframe");
ghostFrame.name = "myFrame";
document.body.appendChild(ghostFrame);
html2canvas(document.body, {
onrendered: function(canvas) {
var test = document.getElementsByClassName('test'); //finding the div.test in the page
$(test).append(canvas); //appending the canvas to the div
var canvas = document.getElementsByTagName('canvas');
$(canvas).attr('id','test'); //assigning an id to the canvas
var can2 = document.getElementById("test");
var dataURL = can2.toDataURL("image/png");
document.getElementById("image_test").src = dataURL; //assigning the url to the image
$(canvas).remove(); //removing the canvas from the page
var tempLink = document.createElement('a'), e;
tempLink.download = 'untitled.png';
if (/(iPad|iPhone|iPod)/g.test(navigator.userAgent)) { //iOS = Iphone, Ipad, etc.
alert("Instructions...");
tempLink.target = "_blank";
tempLink.href = dataURL;
} else {
tempLink.target = ghostFrame.name;
tempLink.href = dataURL.replace(/^data[:]image\/png[;]/i, "data:application/download;");//force download
}
if (document.createEvent) // create a "fake" click-event to trigger the download
{
e = document.createEvent("MouseEvents");
e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
tempLink.dispatchEvent(e);
} else if (tempLink.fireEvent) {
tempLink.fireEvent("onclick");
}
},
logging:true,
background: "#fff",
});
});
Alternative solution (not work in iOS):
You will have to upload the file to the server and then set the required headers for download, see:
Upload image
Download image with .htaccess (add "htaccess" just the folder that the images are generated by <canvas>.toDataURL)
Download image with PHP
If this question is repeated then let me know the link of original question because i enable to findout the good link for resolve my current problem.
I am working on phonegap(cordova2.7) camera and making app for android 4.2.I able to take Multiple Picture's from my app.All image are saving in sd card.But I want to write name on the top of taken picture. i enable to find out how can i resolve this issue.
I want to use only javascript, phonegap method,or plugins.i didnot require any java code.
I try to use canvas
var CAM = {};
window.n = 0;
CAM.changePicture = function() {
navigator.camera.getPicture(CAM.onPhotoDataSuccess, CAM.onFail, {
quality : 100,
destinationType : Camera.DestinationType.FILE_URI,
sourceType : Camera.PictureSourceType.CAMERA,
encodingType : 0,
saveToPhotoAlbum : true
});
};
CAM.onPhotoDataSuccess = function(imageURI) {
var c=document.createElement('canvas');
var ctx=c.getContext("2d");
ctx.font = "20px arial";
ctx.drawImage(imageURI,10,10);
ctx.fillText("Hello",30,30);
var gotFileEntry = function(fileEntry) {
var gotFileSystem = function(fileSystem) {
alert(3);
fileSystem.root.getDirectory("AndroidClinic11/"
+ CAMFUNC.folderName(), {
create : true
}, function(dataDir) {
n++;
var newFileName = CAMFUNC.folderName() + " " + n + ".jpg";
fileEntry.moveTo(dataDir, newFileName, null, CAM.onFail);
}, CAM.onFail);
};
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFileSystem,
CAM.onFail);
};
window.resolveLocalFileSystemURI(imageURI, gotFileEntry, CAM.onFail);
CAM.changePicture();
};
CAM.onFail = function() {
console.log("failure");
};
You can use a javascript library like fabric which will allow you to save images/text etc so long as you are using the canvas which is possible in phonegap. Here is the documentation for dealing with images. You may need to load the image from the drive depending on how phonegap deals with images from the camera.