I've been struggling on this for a while.
When I upload an image in a phonegap application with camera.getPicture() and ft.upload() the image is uploaded without file extension. I read it was because of a cache thing, providing a link to the actual file entry or something.
It was annoying me but I moved on since the image was uploaded fine on my server and displayed fine too even without file extension.
But today, we figured images were sometime rotated by 90°.
I instantly made the connection between the missing part of the image data and this issue, and I guess (not sure) I am right on this point.
I read image rotated by 90° could be caused by missing header meta data, so I guess not only the file extension were missing after all..
Could someone explain me what am I missing in the code and what to do or in which direction to look ? That would be awesome.
Here is part of my code (I can give you more if needed)
navigator.camera.getPicture(function(uri) {
try {
var imageURI = uri;
...
var ft = new FileTransfer();
ft.upload(imageURI, "some_script.php", function(r) {
...
Note:The image stored in database seems fine, the issue happens when the image is displayed in an tag.
Here an example of file getting rotate once uploaded (I added manually the .jpg extension so I could upload it on noelshack otherwise not able to). As you can see, the link to image is OK but once in tag it gets rotated
http://image.noelshack.com/fichiers/2015/41/1444168922-35-1444166605.jpg
http://jsfiddle.net/c3ybkqt8/
tl;dr
How to upload an image file entirely with phonegap including file extension & metadata header and not only a sort of cached file entry.
iOS Code
function capturePhoto() {
navigator.camera.getPicture(uploadPhoto, onFail, {
quality: 50,
// allowEdit: true,
correctOrientation: true,
destinationType: Camera.DestinationType.FILE_URL,
// destinationType: Camera.DestinationType.DATA_URL
sourceType: Camera.PictureSourceType.CAMERA
}
);
}
// function onPhotoDataSuccess(imageData) {
// localStorage.setItem("ImageData",imageData);
// localStorage.setItem("captureImgFlag",captureImgFlag);
// window.location = 'profileUserImgUploadInGallary.html';
// }
function onFail(message) {
// alert('Failed because: ' + message);
}
function uploadPhoto(imageURI){
console.log(imageURI);
spinnerplugin.show();
var UserId = localStorage.getItem('UserId');
// imgPostGallary
// var img = document.getElementById('imgPostGallary');
// var imageURI = img.src;
// var imageURI = imageData;
// img.src = imageURI;
// var ImageDataUp = localStorage.getItem('ImageDataUp');
// var imageURI = ImageDataUp;
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var ft = new FileTransfer();
ft.upload(imageURI, encodeURI("http://XYZ/uploadimg?user_id="+UserId+""), winGallary, fail, options);
console.log(ft.upload);
}
function winGallary(rGallary) {
console.log("Code = " + rGallary.responseCode);
console.log("Response = " + rGallary.response);
console.log("Sent = " + rGallary.bytesSent);
spinnerplugin.hide();
window.location = 'profileUserImgUploadInGallary.html';
}
function fail(error) {
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
Hello, here is full example it's working for me capturing photos and set in image tag and upload that photos on server. and still you have facing any problem message me.
<img id="profileImageId">
<script type="text/javascript">
var profileImage = '';
function profileCapturePhotoEdit() {
navigator.camera.getPicture(profileonPhotoDataSuccess, onFail, {
quality: 50,
// allowEdit: true,
correctOrientation: true, // using this your image not roted 90 degree
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.CAMERA }
);
}
function profileonPhotoDataSuccess(imageData) {
localStorage.setItem("imageDataProfile","data:image/jpeg;base64," + imageData);
var imageDataProfile = localStorage.getItem("imageDataProfile");
document.getElementById('profileImageId').src = imageDataProfile;
}
function onFail(message) {
// alert('Failed because: ' + message);
}
</script>
<!-- uploadProfileImage -->
<button onclick="uploadProfileImage();">
Upload Profile Image
</button>
<script type="text/javascript">
function uploadProfileImage() {
var UserId = localStorage.getItem('UserId');
var img = document.getElementById('profileImageId');
var imageURI = img.src;
var options = new FileUploadOptions();
options.fileKey="file"; // your file key in your .php file change here
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg"; // your extension
var ft = new FileTransfer();
ft.upload(imageURI, encodeURI("http://XYZ?user_id="+UserId+""), winProfile, failProfile, options);
}
function winProfile(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
// alert('Send success');
}
function failProfile(error) {
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
</script>
Related
Upload Images to server selected with CK-Editor
Action Method .Net Core MVC
<script src="~/ckeditor/ckeditor.js"></script>
<script>
CKEDITOR.replace('editor1', {
customConfig: '/js/CustomConfig.js'
});
CKEDITOR.editorConfig = function (config) {
config.removeDialogTabs = 'image:advanced;image:Link;link:advanced;link:upload';
config.filebrowserImageUploadUrl = '/Home/Uploads' //Action for Uploding image
};
</script>
Your upload function should like below. It works for me. And I recommend you also can refer CKEditor FileUpload Helper. It should also help you.
[HttpPost]
public ActionResult UploadImg(IFormFile upload)
{
if (upload.Length <= 0 ) return null;
// check the upload file is image
if (!System.Drawing.Image.FromStream(upload.OpenReadStream()))
{
dynamic error= JsonConvert.DeserializeObject("{ 'uploaded': 0, 'error': { 'message': \"" pls upload img"\"}}");
return Json(error);
}
var fileName = Guid.NewGuid() + Path.GetExtension(upload.FileName).ToLower();
Image image = Image.FromStream(upload.OpenReadStream());
int width = image.Width;
int height = image.Height;
// limit image size
if ((width > 750) || (height > 500))
{
var error = "The file size is wrong. ";
dynamic msg= JsonConvert.DeserializeObject("{ 'uploaded': 0, 'error': { 'message': \"" + error + "\"}}");
return Json(msg);
}
// file size limit, 500k
if (upload.Length > 500 * 1024)
{
var error= "file is too large";
dynamic msg= JsonConvert.DeserializeObject("{ 'uploaded': 0, 'error': { 'message': \"" + error+ "\"}}");
return Json(msg);
}
var path = Path.Combine(
Directory.GetCurrentDirectory(), "wwwroot/images/CKEditorImages",
fileName);
using (var stream = new FileStream(path, FileMode.Create))
{
upload.CopyTo(stream);
}
var url = $"{"/images/CKEditorImages/"}{fileName}";
var successMessage = "upload successfully";
dynamic success = JsonConvert.DeserializeObject("{ 'uploaded': 1,'fileName': \"" + fileName + "\",'url': \"" + url + "\", 'error': { 'message': \"" + successMessage + "\"}}");
return Json(success);
}
I'm creating this app with Phonegap and Framework 7.
In one of my views, i wanted to have a image upload button and i implemented the following code:
<script>
function selectPhoto() {
// Retrieve image file location from specified source
navigator.camera.getPicture(uploadPhoto,
function(message) { alert('get picture failed'); },
{ quality: 50,
destinationType: navigator.camera.DestinationType.FILE_URI,
sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY, }
);
}
function uploadPhoto(imageURI) {
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
var ft = new FileTransfer();
ft.upload(imageURI, "http://pedrofidalgo.pt/upload.php", win, fail, options);
}
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
}
function fail(error) {
alert("An error has occurred: Code = " = error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
</script>
<button class="btngaleria" onclick="selectPhoto();" style="margin-top:3vh; background-color: #5f919d;"> Upload image </button>
I then have a php file on a web server with this code:
<?php
print_r($_FILES);
$new_image_name = $_FILES["file"]["name"];
move_uploaded_file($_FILES["file"]["tmp_name"], "/uploads/sitios".$new_image_name);
?>
I tried building the APK and when i click the button it simply doesn't do anything. When i tried the app in the browser, the console says that the function i'm calling with the button (selectPhoto) is not defined.. can someone give some guidance please?
You have an error in your code
function fail(error)
{
alert("An error has occurred: Code = " = error.code);
should be
function fail(error)
{
alert("An error has occurred: Code = " + error.code);
I'm making a hybrid app with AngularJS and Cordova, using a Laravel 4 API & Backoffice.
I can make a picture with the application, but it does not upload. I don't really know how to upload the picture, and i don't really know how i can troubleshoot all of it.
I upload the image to the API-route i wrote, using the same upload-method as i use to do with the backoffice. This is what i have in the AngularJS-Controller, which uses Cordova to do the stuff.
var pictureSource; // picture source
var destinationType; // sets the format of returned value
pictureSource = navigator.camera.PictureSourceType;
destinationType = navigator.camera.DestinationType;
function clearCache() {
navigator.camera.cleanup();
}
var retries = 0;
function onPhotoDataSuccess(fileURI) {
var win = function (r) {
clearCache();
retries = 0;
alert('Done!');
}
var fail = function (error) {
if (retries == 0) {
retries ++
setTimeout(function() {
onPhotoDataSuccess(fileURI)
alert("kgoa ne keer opnief beginne");
}, 1000)
} else {
retries = 0;
clearCache();
alert('Ups. Something wrong happens!');
}
}
var options = new FileUploadOptions();
options.fileKey = "image";
options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1);
options.mimeType = "image/jpeg";
options.params = {};
params.value1 = "test";
params.value2 = "param";
// if we need to send parameters to the server request
var ft = new FileTransfer();
ft.upload(fileURI, encodeURI("http://10.0.1.13/ClimbrBackoffice/public/api/routes/new/create"), win, fail, options);
}
// Called when a photo is successfully retrieved
//
function onPhotoURISuccess(imageURI) {
// Uncomment to view the image file URI
// console.log(imageURI);
// Get image handle
//
var largeImage = document.getElementById('largeImage');
// Unhide image elements
//
largeImage.style.display = 'block';
// Show the captured photo
// The inline CSS rules are used to resize the image
//
largeImage.src = imageURI;
}
// A button will call this function
//
$scope.capturePhoto = function(){
// Take picture using device camera and retrieve image as base64-encoded string
navigator.camera.getPicture(onPhotoDataSuccess, onFail, {
quality : 100,
destinationType : Camera.DestinationType.FILE_URI,
sourceType : Camera.PictureSourceType.CAMERA,
allowEdit : true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 250,
targetHeight: 400,
saveToPhotoAlbum: true,
correctOrientation: true
});
}
// A button will call this function
//
$scope.getPhoto = function(source) {
// Retrieve image file location from specified source
navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 100,
destinationType: destinationType.FILE_URI,
sourceType: source });
}
I searched the web for good tutorials or explanations, but they drove me crazy.
Can someone please help me out?
Thanks!
Thomas
Your Angular controller should have the following function
$scope.upload = function() {
var options = {
fileKey: "file",
fileName: "image.png",
chunkedMode: false,
mimeType: "image/png"
};
$cordovaFileTransfer.upload("http://yourdomain.com/image_handler", "/android_asset/www/img/ionic.png", options).then(function(result) {
console.log("SUCCESS: " + JSON.stringify(result.response));
$scope.showAlert('Done', 'File Uploaded');
}, function(err) {
console.log("ERROR: " + JSON.stringify(err));
$scope.showAlert('Error', err);
}, function (progress) {
// constant progress updates
});}
And on your server, Laravel function could simply handle the image as:
public function getImageFromDevice(){
$destinationPath = 'uploads/';
$newImageName='MyImage.jpg';
Input::file('file')->move($destinationPath,$newImageName);
}
Do not forget to inject $cordovaFileTransfer in your controller.
That's it, this is a simple example you can extend it.
Credits to: Phonegap + Laravel 4 How to upload file
I have this code which should get the base64 of the captured image, then save it as a jpg into the devices SD card, under the foler MyAppFolder. However it wont work and i cannot figure out why
<html>
<head>
<script src=../cordova.js></script>
<script>
// A button will call this function
//
function capturePhoto() {
sessionStorage.removeItem('imagepath');
// Take picture using device camera and retrieve image as base64-encoded string
navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50, destinationType: Camera.DestinationType.FILE_URI });
}
function onPhotoDataSuccess(imageURI) {
// Uncomment to view the base64 encoded image data
// console.log(imageData);
// Get image handle
//
var imgProfile = document.getElementById('imgProfile');
// Show the captured photo
// The inline CSS rules are used to resize the image
//
imgProfile.src = imageURI;
if(sessionStorage.isprofileimage==1){
getLocation();
}
movePic(imageURI);
}
// Called if something bad happens.
//
function onFail(message) {
alert('Failed because: ' + message);
}
function movePic(file){
window.resolveLocalFileSystemURI(file, resolveOnSuccess, resOnError);
}
//Callback function when the file system uri has been resolved
function resolveOnSuccess(entry){
var d = new Date();
var n = d.getTime();
//new file name
var newFileName = n + ".jpg";
var myFolderApp = "MyAppFolder";
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
//The folder is created if doesn't exist
fileSys.root.getDirectory( myFolderApp,
{create:true, exclusive: false},
function(directory) {
entry.moveTo(directory, newFileName, successMove, resOnError);
},
resOnError);
},
resOnError);
}
//Callback function when the file has been moved successfully - inserting the complete path
function successMove(entry) {
//Store imagepath in session for future use
// like to store it in database
sessionStorage.setItem('imagepath', entry.fullPath);
}
function resOnError(error) {
alert(error.code);
}
</script>
</head>
<body>
<button onclick="capturePhoto()">Take photo</button>
<img src="" id="imgProfile" style=position:absolute;top:0%;left:0%;width:100%;height:100%;>
</body>
</html>
when the button is pressed, the camera doesnt launch.
I solved it as follow. It might help you:
function capturePhoto() {
// Retrieve image file location from specified source
navigator.camera.getPicture(onPhotoSuccess, function(message) {
alert('Image Capture Failed');
}, {
quality : 40,
destinationType : Camera.DestinationType.FILE_URI
});
}
function onPhotoSuccess(imageURI) {
var gotFileEntry = function(fileEntry) {
alert("Default Image Directory " + fileEntry.fullPath);
var gotFileSystem = function(fileSystem) {
fileSystem.root.getDirectory("MyAppFolder", {
create : true
}, function(dataDir) {
var d = new Date();
var n = d.getTime();
//new file name
var newFileName = n + ".jpg";
// copy the file
fileEntry.moveTo(dataDir, newFileName, null, fsFail);
}, dirFail);
};
// get file system to copy or move image file to
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFileSystem,
onFail);
};
// resolve file system for image
window.resolveLocalFileSystemURI(imageURI, gotFileEntry, fsFail);
// file system fail
var onFail = function(error) {
alert("failed " + error.code);
};
var dirFail = function(error) {
alert("Directory" + error.code);
};
The button wont get clicked because your image src is overlapping it.
Change the position of image src and your code shall work fine
anyone got an idea how to embed a webgl animation into powerpoint. any tools that can be used on server side to capture an animated gif?
I did not make it work to embed webgl html directly in a powerpoint.
You can create images of webgl by calling toDataURL() as in
var canvas = document.createElement("canvas");
var gl = canvas.getContext("experimental-webgl");
function render() {
gl.clearColor(Math.random(), Math.random(), Math.random(), 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// takes a 'screenshot' of the canvas.
var image = canvas.toDataURL();
requestAnimationFrame(render);
}
render();
To make an animation you could send each of those screenshots to a server
...
var image = canvas.toDataURL();
var req = new XMLHTTPRequest();
req.open("POST", "http://localhost:8080", true);
var data = {
cmd: 'screenshot',
dataURL: image,
};
req.setRequestHeader("Content-type", "application/json");
req.send(JSON.stringify(data));
Here's a node.js server that will save the screenshots as .png files. You could then load them into some program to turn them into a gif.
var port = 8080
var screenshotCount = 0;
var http = require('http'),
url = require('url'),
fs = require('fs'),
util = require('util'),
path = require('path'),
querystring = require('querystring');
function postHandler(request, callback) {
var query_ = { };
var content_ = '';
request.addListener('data', function(chunk) {
content_ += chunk;
});
request.addListener('end', function() {
query_ = JSON.parse(content_);
callback(query_);
});
}
function sendJSONResponse(res, object) {
res.writeHead(200, {'Content-Type': 'application/json'});
res.write(JSON.stringify(object), 'utf8');
res.end();
}
function startsWith(str, start) {
return (str.length >= start.length &&
str.substr(0, start.length) == start);
}
function saveScreenshotFromDataURL(dataURL) {
var EXPECTED_HEADER = "data:image/png;base64,";
if (startsWith(dataURL, EXPECTED_HEADER)) {
var filename = "screenshot-" + (screenshotCount++) + ".png";
fs.writeFile(
filename,
dataURL.substr(
EXPECTED_HEADER.length,
dataURL.length - EXPECTED_HEADER.length),
'base64');
util.print("Saved Screenshot: " + filename + "\n");
}
}
server = http.createServer(function(req, res) {
// your normal server code
if (req.method == "POST") {
postHandler(req, function(query) {
switch (query.cmd) {
case 'screenshot':
saveScreenshotFromDataURL(query.dataURL);
sendJSONResponse(res, { ok: true });
break;
default:
util.print("err: unknown post: " + query + "\n");
break;
}
});
}
}),
server.listen(port);
Note that server only saves screenshots, it doesn't serve files (for brevity). So you'll need to either add that functionality or serve the files from another server.