• Status: Solved
  • Priority: High
  • Security: Public
  • Views: 148
  • Last Modified:

Send Picture From Android app to External Server using jQuery (ajax)

Hi E's,
When I send pictures from Android app to my server using a form, I use this code (jquery) to do that, with success:
$('#upload').on('click', function() {
    var file_data = $('#ficheiro_upload').prop('files')[0];   
    var form_data = new FormData();                  
    form_data.append('file', file_data);                            
    $.ajax({
                url: 'http://app.xxxxxxxxxxx.com/upload.php',
                dataType: 'text', 
                cache: false,
                contentType: false,
                processData: false,
                data: form_data,                         
                type: 'post',
                success: function(php_script_response){
                    alert(php_script_response); // display response from the PHP script, if any
                }
     });
});  

Open in new window

and the php file:
<?
    if ( 0 < $_FILES['file']['error'] ) {
    echo 'Error: ' . $_FILES['file']['error'] . '';
}
else {
    move_uploaded_file($_FILES['file']['tmp_name'], 'imagem/' . $_FILES['file']['name']);
}
?>

Open in new window

The problem now is, I will not receive the picture in a form (input), the app take the picture and I just have the path to the picture.
This is my index.html file content:
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">

    <link rel="stylesheet" href="materialize/css/materialize.min.css" />

    <script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="materialize/js/materialize.min.js"></script>

    <title>Tirar Foto</title>
</head>

<body>
    <div class="row" style="margin-top: 100px;">
        <div class="col s12 center-align">
            <a class="waves-effect waves-light btn" onclick="tirar_foto();">Tirar Foto</a>
        </div>
        <div class="col s1"></div>
        <div class="col s10 center-align" style="margin-top: 25px;">
            <img id="mostra_imagem" src="" class="responsive-img" />
        </div>
        <div class="col s1"></div>
        <div class="col s12 center-align">
            <a class="waves-effect waves-light btn" onclick="transformar();">Transformar</a>
        </div>
    </div>

    <script type="text/javascript" src="cordova.js"></script>
    <script>
        function tirar_foto() {
            var options = {
                quality: 80,
                destinationType: Camera.DestinationType.FILE_URI,
                encodingType: Camera.EncodingType.JPEG,
                mediaType: Camera.MediaType.PICTURE,
                targetWidth: 1200,
                targetHeight: 800
            }
            navigator.camera.getPicture(success, fail, options);
        }

        function success(thePicture) {
            $("#mostra_imagem").attr("src", thePicture);
            window.caminho = thePicture;
        }

        function fail(e) {
            //alert("Image failed: " + e.message);
        }
        
        function transformar(){
            
            //What I have to do here to send the picture to my server   
            
        }

    </script>
</body>

</html>

Open in new window

What is the best solution in jQuery using ajax, for I send the picture to my server from app when I click in "transformar" button, when I just have path to the picture inside the variable the Picture?
Thank you.

The best regards, JC
0
Pedro Chagas
Asked:
Pedro Chagas
  • 15
  • 10
1 Solution
 
Julian HansenCommented:
Why don't you use the same code - using FormData() - your first example doesn't use a form it uses FormData to assemble the data for the script. In this case you would do the same thing

navigator.camera.getPicture will return the Image encoded as base64 - capture that and append this to your FormData.
0
 
Pedro ChagasWebmasterAuthor Commented:
Hello @Julian,
I try to do like you tell me, but still not work, I have certain I do something wrong...
Maybe I don't know capture...
Can you check my new code please:
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">

    <link rel="stylesheet" href="materialize/css/materialize.min.css" />

    <script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="materialize/js/materialize.min.js"></script>

    <title>Tirar Foto</title>
</head>

<body>
    <div class="row" style="margin-top: 100px;">
        <div class="col s12 center-align">
            <a class="waves-effect waves-light btn" onclick="tirar_foto();">Tirar Foto</a>
        </div>
        <div class="col s1"></div>
        <div class="col s10 center-align" style="margin-top: 25px;">
            <img id="mostra_imagem" src="" class="responsive-img" />
        </div>
        <div class="col s1"></div>
        <div class="col s12 center-align">
            <a class="waves-effect waves-light btn" onclick="transformar();">Transformar</a>
        </div>
    </div>

    <script type="text/javascript" src="cordova.js"></script>
    <script>
        function tirar_foto() {
            var options = {
                quality: 80,
                destinationType: Camera.DestinationType.FILE_URI,
                encodingType: Camera.EncodingType.JPEG,
                mediaType: Camera.MediaType.PICTURE,
                targetWidth: 1200,
                targetHeight: 800
            }
            window.data = navigator.camera.getPicture(success, fail, options);
        }

        function success(thePicture) {
            $("#mostra_imagem").attr("src", thePicture);
        }

        function fail(e) {
            alert("Image failed: " + e.message);
        }
        
        function transformar(){
            var file_data = window.data;
            alert(file_data);
    var form_data = new FormData();                   
    form_data.append('file', file_data);                             
    $.ajax({ 
                url: 'http://app.xxxxxxxxx.com/upload.php', // point to server-side PHP script  
                dataType: 'text',  // what to expect back from the PHP script, if anything 
                cache: false, 
                contentType: false, 
                processData: false, 
                data: form_data,                          
                type: 'post', 
                success: function(php_script_response){ 
                    alert(php_script_response); // display response from the PHP script, if any 
                } 
     });    
        }

    </script>
</body>

</html>

Open in new window

Thank you.
~JC
0
 
Pedro ChagasWebmasterAuthor Commented:
I try also:
var file_data = $('#mostra_imagem').prop('files')[0];

Open in new window


~JC
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
Julian HansenCommented:
Change line 55 to console.log(file_data)
Look in the console (F12) to see what is output
0
 
Pedro ChagasWebmasterAuthor Commented:
Hello @Julian,
The answer of your question/request is "undefined".

After I do the console.log, I change my code for (line 55) for:
var file_data = $('#mostra_imagem');

Open in new window

The output is "[object Object]";
I check what is inside object, and the output is:
{
"0":{},
"length": 1
}

Open in new window


Thank you for your attention.

~JC
0
 
Julian HansenCommented:
Ok I see the problem.

navigator.camera.getPicture calls success, so your AJAX goes in the success

        function success(thePicture) {
            $("#mostra_imagem").attr("src", thePicture);
            window.caminho = thePicture;
            // ADD FROM HERE
            var form_data = new FormData();                   
             form_data.append('file', thePicture);
             $.ajax({ 
                url: 'http://app.xxxxxxxxx.com/upload.php', // point to server-side PHP script  
                dataType: 'text',  // what to expect back from the PHP script, if anything 
                cache: false, 
                contentType: false, 
                processData: false, 
                data: form_data,                          
                type: 'post', 
                success: function(php_script_response){ 
                    alert(php_script_response); // display response from the PHP script, if any 
                } 
           });    
        }

Open in new window

0
 
Pedro ChagasWebmasterAuthor Commented:
Hi @Julian,
I change the code, but still don't work.
I change the code for:
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">

    <link rel="stylesheet" href="materialize/css/materialize.min.css" />

    <script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="materialize/js/materialize.min.js"></script>

    <title>Tirar Foto</title>
</head>

<body>
    <div class="row" style="margin-top: 100px;">
        <div class="col s12 center-align">
            <a class="waves-effect waves-light btn" onclick="tirar_foto();">Tirar Foto</a>
        </div>
        <div class="col s1"></div>
        <div class="col s10 center-align" style="margin-top: 25px;">
            <img id="mostra_imagem" src="" class="responsive-img" />
        </div>
        <div class="col s1"></div>
        <div class="col s12 center-align">
            <!--<a class="waves-effect waves-light btn" onclick="transformar();">Transformar</a>-->
        </div>
    </div>

    <script type="text/javascript" src="cordova.js"></script>
    <script>
        function tirar_foto() {
            var options = {
                quality: 80,
                destinationType: Camera.DestinationType.FILE_URI,
                encodingType: Camera.EncodingType.JPEG,
                mediaType: Camera.MediaType.PICTURE,
                targetWidth: 1200,
                targetHeight: 800
            }
            navigator.camera.getPicture(success, fail, options);
        }

        function success(thePicture) {
            $("#mostra_imagem").attr("src", thePicture);
            // ADD FROM HERE
            alert(thePicture); 
            var form_data = new FormData();                   
             form_data.append('file', thePicture);
            alert(JSON.stringify(form_data, null, 4));
             $.ajax({ 
                url: 'http://app.xxxxxxx.com/upload.php', // point to server-side PHP script   
                dataType: 'text',  // what to expect back from the PHP script, if anything 
                cache: false, 
                contentType: false, 
                processData: false, 
                data: form_data,                          
                type: 'post', 
                success: function(php_script_response){ 
                    alert(php_script_response); // display response from the PHP script, if any 
                } 
           });    
        }
        
        function fail(e) {
            alert("Image failed: " + e.message);
        } 

    </script>
</body>

</html>

Open in new window

I put 2 alert's to view the answer of the variable the Picture, and the object form_data is empty:thePicture variableObject form_data
This is very important for my project.
Thank you again for your attention.

~JC
0
 
Pedro ChagasWebmasterAuthor Commented:
Hi again,
I check in the internet for a solution, and I found this stackoverflow.
I try to implement but also don't word, but maybe can give you some idea about the problem.

~JC
0
 
Julian HansenCommented:
Let us recap - you say the code for the non ajax submit works?

Is that correct?
0
 
Pedro ChagasWebmasterAuthor Commented:
Hi Julian,
The first code that I post in this question, work yes.
The different is, in the first I get the picture from gallery, and now I take them direct from the camara.

Regards, JC
0
 
Julian HansenCommented:
The different is, in the first I get the picture from gallery, and now I take them direct from the camara

So you have not (as yet) successfully grabbed the picture from the camera yet in any scenario - is that correct?
0
 
Pedro ChagasWebmasterAuthor Commented:
No.
The only thing I can do, is take the picture with the camara, show them in screen, and try send to my server without success.

Thank you.
~JC
0
 
Pedro ChagasWebmasterAuthor Commented:
Maybe the cache was the problem.
What is your opinion?
0
 
Julian HansenCommented:
So this question is actually about how to retrieve the camera image so you can send it to the server?

How are you displaying the image currently?
0
 
Pedro ChagasWebmasterAuthor Commented:
I display the image inside a div (#mostra_imagem), in the same way of the code that works.
I think, the difference between them, is one are on gallery, and the other is in cache.
My English not was the best...
0
 
Julian HansenCommented:
No cache is not the issue

Ok, after you display the image in the mostra_imagem <img> and you right click on the image and select Inspect Element from the menu what do you see in the source - I am guessing you will see a base-64 encoded string?
0
 
Pedro ChagasWebmasterAuthor Commented:
Hi @Julian,
I try to show you the source, but I don't found any debuger for view the code running. Usually I use chrome for that, but in this particular case is not possible, because the browser don't take pictures.
I keep searching for give you a answer.

~JC
0
 
Julian HansenCommented:
Ok, I understand - mobile browser.

I am not sure if this is the best way of solving this but it should work. If you say you are able to set the camera image to an <img> element and it displays then we can use this code to get the image out of the <img> element and send it by AJAX
The general idea is we put the image in a <canvas> element then use the canvas toBlob() to get the image. We then add this to the FormData element.
// CREATE A canvas ELEMENT TO PUT THE IMAGE IN
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

// GET THE <img> THAT HAS THE CAMERA IMAGE
var img = document.getElementById('theimg');
// ADD THE IMAGE TO THE CANVAS (NOTE THE CANVAS IS NOT ATTACHED TO THE DOM 
// SO IT WILL NOT DISPLAY
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0 );

// toBlob CALLS A CALLBACK WHEN DONE
canvas.toBlob(function(blob) {
  // CREATE formData OBJET
  var fd = new FormData();

  // AND APPEND BLOB WITH FIELDNAME TO USE AND NAME 
  // TO USE FOR FILE (theimage.png - CHANGE AS REQUIRED)
  fd.append('filename', blob, 'theimage.png');
  $.ajax({
    url: 'ajaxscript/goes/here', 
    type: 'POST',
    data: fd,
    processData: false, // IMPORTANT
    contentType: false // IMPORTANT
  }).then(function(resp) {
    // HANDLE RESPONSE OF AJAX
  });
})
});

Open in new window

With the above code the file will be sent to the server as follows (Example)
Array
(
    [name] => theimage.png
    [type] => image/png
    [tmp_name] => C:\Windows\Temp\phpA3DF.tmp
    [error] => 0
    [size] => 13925
)

Open in new window

0
 
Pedro ChagasWebmasterAuthor Commented:
Hello @Julian,
I try to implement your code, but maybe I did something wrong.
Now we have:
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">

    <link rel="stylesheet" href="materialize/css/materialize.min.css" />

    <script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="materialize/js/materialize.min.js"></script>

    <title>Tirar Foto</title>
</head>

<body>
    <div class="row" style="margin-top: 100px;">
        <div class="col s12 center-align">
            <a class="waves-effect waves-light btn" onclick="tirar_foto();">Tirar Foto</a>
        </div>
        <div class="col s1"></div>
        <div class="col s10 center-align" style="margin-top: 25px;">
            <img id="mostra_imagem" src="" class="responsive-img" />
        </div>
        <div class="col s1"></div>
        <div class="col s12 center-align">
            <!--<a class="waves-effect waves-light btn" onclick="transformar();">Transformar</a>-->
        </div>
    </div>

    <script type="text/javascript" src="cordova.js"></script>
    <script>
        function tirar_foto() {
            var options = {
                quality: 80,
                destinationType: Camera.DestinationType.FILE_URI,
                encodingType: Camera.EncodingType.JPEG,
                mediaType: Camera.MediaType.PICTURE,
                targetWidth: 1200,
                targetHeight: 800
            }
            navigator.camera.getPicture(success, fail, options);
        }

        function success(thePicture) {
            $("#mostra_imagem").attr("src", thePicture);

//@Julian code begin//////////////////////////////////////////////////////////////////////////////             
            // CREATE A canvas ELEMENT TO PUT THE IMAGE IN
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

// GET THE <img> THAT HAS THE CAMERA IMAGE
var img = document.getElementById('mostra_imagem');
// ADD THE IMAGE TO THE CANVAS (NOTE THE CANVAS IS NOT ATTACHED TO THE DOM 
// SO IT WILL NOT DISPLAY
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0 );

// toBlob CALLS A CALLBACK WHEN DONE
canvas.toBlob(function(blob) {
  // CREATE formData OBJET
  var fd = new FormData();

  // AND APPEND BLOB WITH FIELDNAME TO USE AND NAME 
  // TO USE FOR FILE (theimage.png - CHANGE AS REQUIRED)
  fd.append('filename', blob, 'theimage.png');
  $.ajax({
    url: 'http://app.gloradin.com/upload.php', 
    type: 'POST',
    data: fd,
    processData: false, // IMPORTANT
    contentType: false // IMPORTANT
  }).then(function(resp) {
    alert(resp);
  });
});
  //@Julian code end/////////////////////////////////////////////////////////////////////////////         
        }
        
        function fail(e) {
            alert("Image failed: " + e.message);
        } 

    </script>
</body>
</html>

Open in new window

The only line I changed in your code was this one:
var img = document.getElementById('theimg');

Open in new window

for this:
var img = document.getElementById('mostra_imagem');

Open in new window

.
Maybe I implement wrong your solution in my code.
Can you check please?
Thank you,

~JC
0
 
Pedro ChagasWebmasterAuthor Commented:
Also, I tried to get a answer from the server with this php code:
<?
    if ( 0 < $_FILES['file']['error'] ) {
    echo 'Error: ' . $_FILES['file']['error'] . '';
}
else {
    move_uploaded_file($_FILES['file']['tmp_name'], 'imagem/' . $_FILES['file']['name']);
}

echo $_FILES['file']['tmp_name'];
?>

Open in new window

...and the output is empty.
0
 
Pedro ChagasWebmasterAuthor Commented:
The output of
var img = document.getElementById('theimg');

Open in new window

is null;
The output of
var img = document.getElementById('mostra_imagem');

Open in new window

is {}

Maybe now the problem was the html?!
0
 
Julian HansenCommented:
I cannot test your code but have you checked that the image (mostra_imagem) is being populated with the image from the camera?

The first step is to go back to the code where you are able to assign the image from the camera to an image on the page (<img id="mostra_imagem") - the picture must display (Does line 46 result in the image being shown on the screen?)

Then create a button linked to the code I gave you so when you click the button it fetches the image as per my code.

Point the AJAX to this script
reflect.php
<?php
print_r($_FILES);

Open in new window

This script will show you what is being sent in the $_FILES array - we want to see this populated with data - if it is we know the script is working
0
 
Pedro ChagasWebmasterAuthor Commented:
Thank you Julian,
This is the code that works:
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">

    <link rel="stylesheet" href="materialize/css/materialize.min.css" />

    <script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="materialize/js/materialize.min.js"></script>

    <title>Tirar Foto</title>
</head>

<body>
    <div class="row" style="margin-top: 100px;">
        <div class="col s12 center-align">
            <a class="waves-effect waves-light btn" onclick="tirar_foto();">picture</a>
            <a class="waves-effect waves-light btn" onclick="julian();">send</a>
        </div>
        <div class="col s1"></div>
        <div class="col s10 center-align" style="margin-top: 25px;">
            <img id="mostra_imagem" src="" class="responsive-img" />
        </div>
        <div class="col s1"></div>
        <div class="col s12 center-align">
            <!--<a class="waves-effect waves-light btn" onclick="transformar();">Transformar</a>-->
        </div>
    </div>

    <script type="text/javascript" src="cordova.js"></script>
    <script>
        function tirar_foto() {
            var options = {
                quality: 80,
                destinationType: Camera.DestinationType.FILE_URI,
                encodingType: Camera.EncodingType.JPEG,
                mediaType: Camera.MediaType.PICTURE,
                targetWidth: 1200,
                targetHeight: 800
            }
            navigator.camera.getPicture(success, fail, options);
        }

        function success(thePicture) {
            $("#mostra_imagem").attr("src", thePicture);    
        }
        
        function fail(e) {
            alert("Image failed: " + e.message);
        } 
        
        function julian(){      
            // CREATE A canvas ELEMENT TO PUT THE IMAGE IN
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

// GET THE <img> THAT HAS THE CAMERA IMAGE
var img = document.getElementById('mostra_imagem');
// ADD THE IMAGE TO THE CANVAS (NOTE THE CANVAS IS NOT ATTACHED TO THE DOM 
// SO IT WILL NOT DISPLAY
//canvas.width = img.width;
canvas.width = "1200";
//canvas.height = img.height;
canvas.height = "800";
context.drawImage(img, 0, 0 );     
        
// toBlob CALLS A CALLBACK WHEN DONE
canvas.toBlob(function(blob) {
  // CREATE formData OBJET
  var fd = new FormData();
  // AND APPEND BLOB WITH FIELDNAME TO USE AND NAME 
  // TO USE FOR FILE (theimage.png - CHANGE AS REQUIRED)
  fd.append('filename', blob, 'theimage.png');
  $.ajax({
    url: 'http://app.xxxxxxxx.com/xxxxxxxx.php', 
    type: 'POST',
    data: fd,
    processData: false, // IMPORTANT
    contentType: false // IMPORTANT
  }).then(function(resp) {
    alert(resp);
  });
});
        }
    </script>
</body>

</html>

Open in new window

0
 
Julian HansenCommented:
You are welcome.
1
 
Pedro ChagasWebmasterAuthor Commented:
Thank you @Julian,
Can you please help me in this question:
https://www.experts-exchange.com/questions/29091087/PHP-don't-recognize-jpg-file-from-canvas.html

Thank you
~ JC
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 15
  • 10
Tackle projects and never again get stuck behind a technical roadblock.
Join Now