javascript - 使用 JavaScript 在解析中保存图像

标签 javascript jquery html parse-platform

我能够在 Parse 中存储字符串和数字,但在 Parse 中存储图像时遇到问题。

本质上,用户从他们的图库中选择一个图像,然后将该图像插入到具有如下 id 的图像中:

        <img src="content/profilef.png" id="profilePic1" />
        <img src="content/profile.png" id="profilePic2" />

        <img src="content/profileu.png" id="profilePic3" />

这就是我试图抓取并存储到 Parse 中的内容,我已经在解析中创建了 3 个文件列。

这是我的 JavaScript 代码,除了我尝试存储的图像之外,一切都正常:

function accountCreation(event){
    event.preventDefault();
    var bio = document.getElementById("profileDescription").value;
    var city = document.getElementById("selectCity").value;
    var men = document.getElementById("selectMen").checked;
    var women = document.getElementById("selectWomen").checked;

       var profilePic1 = document.getElementById("profilePic1").value;

                            var profilePic2 = document.getElementById("profilePic2").value;
                            var profilePic3 = document.getElementById("profilePic3").value;





    var user = Parse.User.current();
        user.set("profilePic1", profilePic1);
        user.set("profilePic2", profilePic2);
        user.set("profilePic3", profilePic3);

    user.set("bio", bio);
    user.set("city", city);
    user.set("menPreference", men);
    user.set("womenPreference", women);

    user.save(null, {
        success: function(user) {
            alert("succesfully stored");
        },

        error: function(user, error) {
            alert('error' + error.message);
        }
    });
}

提前致谢,

更新: 因为我正在使用Intel XDK(或phonegap),所以我无法在本地使用php,所以我必须将php代码托管在云端。,下面是我得到的错误

Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.

 failed to create file, src= content/profilef.png, encoded img=
accountCreation.js:56 failed to create file, src= content/profile.png, encoded img=
accountCreation.js:56 failed to create file, src= content/profileu.png, encoded img=

脚本

$(function() {

    //Initialize Parse below by using credentials provided for App on Parse 
Parse.initialize("ID", "ID");

// click handlers
    // this watches for clicks to save user data 
    $('#accountCreation').click(function(event){
        event.preventDefault(); // only needed if the clicked element is a link
        accountCreation();
    })




    function accountCreation(){
            $('#container').hide(); // hide the display while we save the info as it will take a few seconds, you should do a loading bar or something here instead

            var user = Parse.User.current(); // get the currently logged in user object
            var bio = $('#profileDescription').val();
            var city = $('#selectCity').val();
            var men = $('#selectMen').is(':checked'); // returns true or false
            var women = $('#selectWomen').is(':checked'); // returns true or false

            // $('.images') retruns an array of elements with the class name "images"
            // loop through each image element
            $('.images').each(function(index, element) {
                  // first we'll need to get the image source 
                  var src = $(element).attr('src');
                  // alone, the source is just a url and not of much use to us
                  // we'll need to take the source and create a base64 encoded string from it
                  // we'll use an ajax call to a small php script to do this
                  var encodedImg;
                  try {
                    $.ajax({
                       type: "POST",
                       url: "http://addo-env.elasticbeanstalk.com/aws/encodeImgToBase64.php", // you may need to adjust this path depending on where you store the file in relation to this file
                       data: 'url='+src,
                       success: function(data){
                         encodedImg = data; // encodedImg is now a base64 encoded string 
                       },
                       async: false 
                       // note the use of `async: false` here
                       // normally the ajax call would run asynchronously in the background  
                       // and the below code would be run immediately, even before the ajax call has finished 
                       // `async: false` stops execution here and forces the ajax call to finish before any other code is run 
                       // this isnt normally a great way to do this since it locks up the page while the funcion is working
                       // but, honestly, this is a save function and its pretty standard for other features on a page to be unavailable while saving data
                       // that said, this could be written better with `promises` but it works as is
                     });
                    var file = new Parse.File("photo.jpg", { base64: encodedImg }); // this part actually saves the image file to parse
                    // From the Docs: Notice in this example that we give the file a name of photo.jpg. You don't need to worry about filename collisions. 
                    // Each upload gets a unique identifier so there's no problem with uploading multiple files named photo.jpg.
                    user.set("image"+index,file); // set this image to the corosponding column on our object 
                  } catch (e) {
                    console.log('failed to create file, src= '+src+', encoded img='+encodedImg)
                  }
            });
            user.set("bio", bio);
            user.set("city", city);
            user.set("menPreference", men);
            user.set("womenPreference", women);
            // save our new 
            user.save(null,{
              success: function(user) { 
                  $('#message').html('Profile Updated!');
                  $('#container').show(); // show the screen again, you should just remove your loading bar now if you used one
              },
              error: function(user, error) {
                  console.log('Failed to create new object, with error code: ' + error.message);
              }
            });
     }

更新2:

<?php
header('Access-Control-Allow-Origin: *');
if (isset($_POST['url']) ){
    echo base64_encode(file_get_contents($_POST['url']));
}else{
    echo 'Error: No image to encode';
}
?>

这是上面的PHP代码,它有 header 访问控制允许允许跨域访问,如果没有 header ,我会收到错误。它托管在 aws 上,链接如下:

http://addo-env.elasticbeanstalk.com/aws/encodeImgToBase64.php

我无法将其存储在本地,因为 php 无法与phonegap 或 intel xdk 配合使用,因此必须将其托管在云端

最佳答案

不幸的是,Parse.com 无法直接从 url 保存图像文件。因为您想从页面上的 img 标记获取图像(而不是用户上传图像的输入),所以您需要使用 canvas元素将图像转换为 base64 编码字符串,使用这些字符串保存解析文件,然后将文件与您的用户关联,最后保存用户对象。

下面我还将向您展示如何检索和显示存储的图像。注释应该可以解释大部分内容。

此外,here is a fully working demo这样你就可以看到它是如何工作的

jQuery:

// click handler
// this watches for clicks to save user data 
$('#accountCreation').click(function(event){
    event.preventDefault(); // only needed if the clicked element is a link
    accountCreation();
})

function accountCreation(){
    $('#container').hide(); // hide the display while we save the info as it will take a few seconds, you should do a loading bar or something here instead
    var user = Parse.User.current(); // get the currently logged in user object

    // loop through each image element
    var promises = $('.images').map(function(index, element) {
        var deferred = $.Deferred();
        var src = $(element).attr('src');
        var canvas = document.createElement('CANVAS');
        var ctx = canvas.getContext('2d');
        var img = new Image;
        img.crossOrigin = 'Anonymous';
        img.onload = function(){
            canvas.height = img.height;
            canvas.width = img.width;
            ctx.drawImage(img,0,0);
            var base64Img = canvas.toDataURL('image/png');
            // Clean up
            canvas = null; 
            deferred.resolve(base64Img);
        };
        img.src = element.src;
        return deferred;
    });
    $.when.apply($, promises).then(function() {
        // arguments[0][0] is first result
        // arguments[1][0] is second result and so on
        for (var i = 0; i < arguments.length; i++) {
            var file = new Parse.File("photo.jpg", { base64: arguments[i]}); // this part actually saves the image file to parse
            user.set("image" + i, file); // set this image to the corosponding column on our object 
        }
        var bio = $('#profileDescription').val();
        var city = $('#selectCity').val();
        var men = $('#selectMen').is(':checked'); // returns true or false
        var women = $('#selectWomen').is(':checked'); // returns true or false

        user.set("bio", bio);
        user.set("city", city);
        user.set("menPreference", men);
        user.set("womenPreference", women);

        // save the user object
        user.save(null,{
          success: function(user) { 
                  $('#message').html('Profile Updated!');
                  $('#container').show(); // show the screen again, you should just remove your loading bar now if you used one
          },
          error: function(user, error) {
                  console.log('Failed to create new object, with error code: ' + error.message);
          }
        });
    });
 }


// the below function demonstrates how to retrieve and display images stored on parse       
$('#loadUserData').click(function(){
      event.preventDefault(); // only needed if the clicked element is a link
      var user = Parse.User.current(); 



      var image0 = user.get("image0"); // get the stored image objects
      var image1 = user.get("image1");
      var image2 = user.get("image2");
      // make sure we found images
      if(image0 && image1 && image2){
          var imgElement0 = $('<img>'); // create an image tag
          imgElement0.attr('src', image0.url()); // set the souce or the img tag to the url of the image objct
          $('#image0').html(imgElement0); // display the image

          var imgElement1 = $('<img>');
          imgElement1.attr('src', image1.url());
          $('#image1').html(imgElement1);

          var imgElement2 = $('<img>');
          imgElement2.attr('src', image2.url());
          $('#image2').html(imgElement2);


          var bio = user.get("bio");
          $('#bio').html(bio);

          var city = user.get("city");
          $('#city').html(city);

          var menPreference = user.get("menPreference");
          $('#menPreference').html(menPreference);

          var womenPreference = user.get("womenPreference");
          $('#womenPreference').html(womenPreference);
          $('#message').html('Data retrieved!');
      }
      else{ 
        alert('No data available on the user object. Click "Update Profile" to store the data'); 
      }
  })        

我在示例中使用的 sudo-html:

<div style="margin:auto;width:600;">
<table width="600" border="1" style="margin-left:25px; float:left;">
  <tbody>
    <tr>
      <td>Image 1:</td>
      <td> <img src="http://i.imgur.com/QxD2r0x.png" class="images" /></td>
    </tr>
    <tr>
      <td>Image 2:</td>
      <td> <img src="http://i.imgur.com/sIxiQWH.png" class="images" /></td>
    </tr>
    <tr>
      <td>Image 3:</td>
      <td> <img src="http://i.imgur.com/FgSuSKO.png" class="images" /></td>
    </tr>
    <tr>
      <td>Men:</td>
      <td> <input type="checkbox" id="selectMen" checked /></td>
    </tr>
    <tr>
      <td>Women:</td>
      <td><input type="checkbox" id="selectWomen" checked /></td>
    </tr>
    <tr>
      <td>City: </td>
      <td><input type="text" id="selectCity" value="My city..." /></td>
    </tr>
    <tr>
      <td>Description:</td>
      <td><textarea id="profileDescription">My cool description..."</textarea></td>
    </tr>
    <tr>
      <td colspan="2" style="padding:25px;"><a href="#" id="accountCreation" class="btnLink">Update profile!</a></td>
    </tr>
  </tbody>
</table>


<table width="600" border="1" style="margin-left:25px; float:left;">
  <tbody>
    <tr>
      <td colspan="2" style="padding:25px;"><a href="#" id="loadUserData" class="btnLink">Click Here To Load Stored User Data Below</a></td>
    </tr>
    <tr>
      <td colspan="2" style="padding:25px;"><a href="#" id="resetUser" class="btnLink">Click Here To Reset User</a></td>
    </tr>
    <tr>
      <td>Image 1:</td>
      <td id="image0"></td>
    </tr>
    <tr>
      <td>Image 2:</td>
      <td id="image1"></td>
    </tr>
    <tr>
      <td>Image 3:</td>
      <td id="image2"></td>
    </tr>
    <tr>
      <td>Men: </td>
      <td id="menPreference"></td>
    </tr>
    <tr>
      <td>Women:  </td>
      <td id="womenPreference"></td>
    </tr>
    <tr>
      <td>City:</td>
      <td id="city"> </td>
    </tr>
    <tr>
      <td>Description:</td>
      <td id="bio"></td>
    </tr>
  </tbody>
</table>
<div>

关于javascript - 使用 JavaScript 在解析中保存图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28890816/

相关文章:

javascript - 我的 HTML 中包含的 JavaScript 库能否使用 cookie session 向我的网站发出请求?

javascript - jQuery 从 xml 文档中提取属性

javascript - 在 JQuery 中创建动态创建元素的事件

javascript - 性能:jQuery remove() 与 JavaScript removeChild()

jquery - show 从 Div 隐藏内容,默认先显示

javascript - 向 select2 添加选项而不更改其当前状态

javascript - 为什么代码的第一部分无法正常工作,而第二部分却可以正常工作?

javascript - 在使用 Sequelize 钩子(Hook)运行之前修改选择查询

php - 浏览器忽略来自 ajax 响应的 header 刷新

javascript - 使用 JavaScript 添加行和排序表