1

I am developing a page that uses your webcam to take picture and upload it to the s3 bucket. The upload is successful but the file is blank when you opened it. I notice this one at the console when you upload to s3. Screencap of POST response

The codes uploaded the photo as document. So my question is how to upload the photo as a photo not as document? This is the codes that i used. Thank you for your help

    <?php
$access_key         = ""; //User Access Key
$secret_key         = ""; //secret key
$my_bucket          = "recogtest"; //bucket name
$region             = "us-west-2"; //bucket region
$allowd_file_size   = "1048579, 10485760"; //This example allows a file size from 1 to 10 MiB

//dates
$short_date         = gmdate('Ymd'); //short date
$iso_date           = gmdate("Ymd\THis\Z"); //iso format date
$expiration_date    = gmdate('Y-m-d\TG:i:s\Z', strtotime('+1 hours')); //policy expiration 1 hour from now
$presigned_url_expiry    = 3600; //Presigned URL validity expiration time (3600 = 1 hour)

$policy = array(
'expiration' => gmdate('Y-m-d\TG:i:s\Z', strtotime('+6 hours')),
'conditions' => array(
    array('bucket' => $my_bucket),  
    array('acl' => 'public-read'),  
    array('starts-with', '$key', ''),  
    array('starts-with', '$Content-Type', ''),  
    array('success_action_status' => '201'),  
    array('x-amz-credential' => implode('/', array($access_key, $short_date, $region, 's3', 'aws4_request'))),  
    array('x-amz-algorithm' => 'AWS4-HMAC-SHA256'),  
    array('x-amz-date' => $iso_date),  
    array('x-amz-expires' => ''.$presigned_url_expiry.''),  
));

$policybase64 = base64_encode(json_encode($policy));    

$kDate = hash_hmac('sha256', $short_date, 'AWS4' . $secret_key, true);
$kRegion = hash_hmac('sha256', $region, $kDate, true);
$kService = hash_hmac('sha256', "s3", $kRegion, true);
$kSigning = hash_hmac('sha256', "aws4_request", $kService, true);
$signature = hash_hmac('sha256', $policybase64 , $kSigning);
?>
<h1>Upload New Face to Your System</h1>
<div class="form-wrp">

<form action="https://<?=$my_bucket?>.s3-<?=$region?>.amazonaws.com" method="post" id="aws_upload_form"  enctype="multipart/form-data">

<div id="my_camera"></div>
 <input type=button value="Enable camera" onClick="configure()">
 <input type=button value="Take Snapshot" onClick="take_snapshot()">
 <input type=button value="Save Snapshot" onClick="saveSnap()">

 <div id="results" ></div>

<input type="hidden" name="acl" value="public-read">
<input type="hidden" name="success_action_status" value="201">
<input type="hidden" name="policy" value="<?=$policybase64?>">
<input type="hidden" name="X-amz-credential" value="<?=$access_key?>/<?=$short_date?>/<?=$region?>/s3/aws4_request">
<input type="hidden" name="X-amz-algorithm" value="AWS4-HMAC-SHA256">
<input type="hidden" name="X-amz-date" value="<?=$iso_date?>">
<input type="hidden" name="X-amz-expires" value="<?=$presigned_url_expiry?>">
<input type="hidden" name="X-amz-signature" value="<?=$signature?>">
<input type="hidden" id="key" name="key" value="">
<input type="hidden" id="content-type" name="Content-Type" value="images/jpeg">
//<input type="file" id='file' name="file" />
<input type="submit" value="Upload File" />
</form>
</div>
</div>

<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript" src="webcam.js"></script>
<script language="JavaScript">
// Configure a few settings and attach camera
 function configure(){
  Webcam.set({
   width: 320,
   height: 240,
   image_format: 'jpeg',
   jpeg_quality: 90
  });
  Webcam.attach( '#my_camera' );
 }

 function take_snapshot() {
  // play sound effect
  //shutter.play();

  // take snapshot and get image data
  Webcam.snap( function(data_uri) {
 // display results in page
  document.getElementById('results').innerHTML = 
   '<img id="imageprev" src="'+data_uri+'"/>';
  } );

  Webcam.reset();
 } 

function saveSnap(){
 // Get base64 value from <img id='imageprev'> source
 var base64image = document.getElementById("imageprev").src;

 Webcam.upload( base64image, 'upload.php', function(code, text) {
  console.log('Save successfully');
  console.log(text);
  $('#key').val(text); 
  $('#content-type').val('images/jpeg');
 });

}
</script>

<script>
$("#aws_upload_form").submit(function(e) {
    e.preventDefault();

    var post_url = $(this).attr("action"); //get form action url
    var form_data = new FormData(this); //Creates new FormData object
    $.ajax({
        url : post_url,
        type: 'post',
        datatype: 'xml',
        data : form_data,
        contentType: false,
        processData:false,
        xhr: function(){
            var xhr = $.ajaxSettings.xhr();
            if (xhr.upload){
                var progressbar = $("<div>", { style: "background:#607D8B;height:10px;margin:10px 0;" }).appendTo("#results"); //create progressbar
                xhr.upload.addEventListener('progress', function(event){
                        var percent = 0;
                        var position = event.loaded || event.position;
                        var total = event.total;
                        if (event.lengthComputable) {
                            percent = Math.ceil(position / total * 100);
                            progressbar.css("width", + percent +"%");
                        }
                }, true);
            }
            return xhr;
        }
    }).done(function(response){
        console.log(response);
        var url = $(response).find("Location").text(); //get file location
        var the_file_name = $(response).find("Key").text(); //get uploaded file name
        $("#results").html("<span>File has been uploaded, Here's your file <a href=" + url + ">" + the_file_name + "</a></span>"); //response
    })/*.error(function() {
      console.log( arguments);
    });*/
});

2 Answers2

0

uploaded the photo as document

Can you clarify how you know this? My suspicion is because you looked at the content-type metadata for the object in the S3 bucket. The way to fix this is to specify the content-type when uploading. See this question for something similar:

aws s3api put-object --bucket bucket --key foo.json --body foo.json --content-type application/json

In your case, content-type would be image/jpeg

MyStackRunnethOver
  • 4,872
  • 2
  • 28
  • 42
  • Because when i opened the uploaded file on s3 i does have.jpeg but there is no picture just a blank white. Actually i don't really understand those json line on where to put it because I don't have those in my codes, if i share my codes will that help? – Muhamad Asyraf Othman May 13 '20 at 06:41
0

You need to keep the default content type

<input type="text" id="content-type" name="Content-Type" value="image/jpeg">

Then upload your photo.

In the end when calling the upload function, just change

contentType : false

To

contentType: 'image/jpeg'
Shubham Jain
  • 5,327
  • 2
  • 15
  • 38
  • Hi I tried to enter value="image/jpeg"> as you suggested but the value is still the same. i have edited my post to show the whole code. Can you please modify it? The sequence of the button is as Enable camera > Take Snapshot > Save Snapshot > Upload File – Muhamad Asyraf Othman May 13 '20 at 18:54
  • Hi I changed the code with contentType: 'image/jpeg' but the file is failed to upload. On the console it says 412 (Precondition Failed) – Muhamad Asyraf Othman May 14 '20 at 07:23
  • Remove it from conditions – Shubham Jain May 14 '20 at 07:25
  • 'conditions' => array( array('bucket' => $my_bucket), array('acl' => 'public-read'), array('starts-with', '$key', ''), array('success_action_status' => '201'), array('x-amz-credential' => implode('/', array($access_key, $short_date, $region, 's3', 'aws4_request'))), array('x-amz-algorithm' => 'AWS4-HMAC-SHA256'), array('x-amz-date' => $iso_date), array('x-amz-expires' => ''.$presigned_url_expiry.''), )); – Shubham Jain May 14 '20 at 07:25
  • Change this array('starts-with', '$Content-Type', '') to array('starts-with', '$Content-Type', 'image/jpeg') in conditions, if this doesn't work then Sry I can't help – Shubham Jain May 14 '20 at 07:36
  • it now shows 403 Forbidden. Thank you for helping and sorry for late replies :) – Muhamad Asyraf Othman May 14 '20 at 07:50