将从URL中提取的图像转换为base64

时间:2016-12-03 11:24:44

标签: javascript angularjs facebook cordova ionic-framework

每当他们通过Facebook登录时,我都会获取用户的Facebook个人资料图片。我想从URL将图像转换为base 64。这样做的最佳方式是什么,同时确保用户仍然可以在视图中查看他们的个人资料图片(home.view)?目前,我直接指的是URL。

到目前为止,这是我的代码:

facebook.service.js

Startup

home.controller.js

function FacebookService($http, config) {
      this.getUserPicture = function(userId, token) {
      return $http({
        method: 'GET',
        url: 'https://graph.facebook.com/' + userId + '/picture?type=large&redirect=false'
      })
    }
  }

home.view.js

function HomeController($scope, $cordovaNativeStorage, FacebookService, $ionicLoading) {
  if (window.cordova) {
    // Get Facebook access token
    $cordovaNativeStorage.getItem("facebookAccessToken").then(function(value) {
      $scope.facebookAccessToken = value

      // Get Facebook user picture (currently stored as a URL, would want to store it as a base 64 string which can be displayed as an image
      FacebookService.getUserPicture($scope.facebookUserData.id).then(function(dataResponse) {
        $scope.facebookUserPicture = dataResponse.data;

        // Save Facebook user picture
        $cordovaNativeStorage.setItem("facebookUserPicture", $scope.facebookUserPicture).then(function() {}, function(error) {
          console.error("Unable to cache user data: " + result);
          $ionicLoading.show({
            template: 'Unable to cache user data',
            duration: 1500
          })
        });
      }, function(error) {
        console.log(error.data.error.message)
      })
    }, function(error) {
      console.log(error.data.error.message)
    })
  }
};

3 个答案:

答案 0 :(得分:2)

有一种方法可以通过画布(source)来完成:

var convertImgToDataURLviaCanvas = function(url, callback) {
  var img = new Image();

  img.crossOrigin = 'Anonymous';

  img.onload = function() {
    var canvas = document.createElement('CANVAS');
    var ctx = canvas.getContext('2d');
    var dataURL;
    canvas.height = this.height;
    canvas.width = this.width;
    ctx.drawImage(this, 0, 0);
    dataURL = canvas.toDataURL();
    callback(dataURL);
    canvas = null;
  };

  img.src = url;
}

convertImgToDataURLviaCanvas( 'http://some.com/images/1.jpg', function( base64_data ) {
    console.log( base64_data );
} );

答案 1 :(得分:1)

您可以使用此辅助函数来获取网址并转换为dataURI。

library(dplyr)
mtcars %>% 
    group_by(cyl, gear) %>%
    summarise_all("mean")

# Source: local data frame [8 x 11]
# Groups: cyl [?]
# 
#     cyl  gear    mpg     disp       hp     drat       wt    qsec    vs    am     carb
#   <dbl> <dbl>  <dbl>    <dbl>    <dbl>    <dbl>    <dbl>   <dbl> <dbl> <dbl>    <dbl>
# 1     4     3 21.500 120.1000  97.0000 3.700000 2.465000 20.0100   1.0  0.00 1.000000
# 2     4     4 26.925 102.6250  76.0000 4.110000 2.378125 19.6125   1.0  0.75 1.500000
# 3     4     5 28.200 107.7000 102.0000 4.100000 1.826500 16.8000   0.5  1.00 2.000000
# 4     6     3 19.750 241.5000 107.5000 2.920000 3.337500 19.8300   1.0  0.00 1.000000
# 5     6     4 19.750 163.8000 116.5000 3.910000 3.093750 17.6700   0.5  0.50 4.000000
# 6     6     5 19.700 145.0000 175.0000 3.620000 2.770000 15.5000   0.0  1.00 6.000000
# 7     8     3 15.050 357.6167 194.1667 3.120833 4.104083 17.1425   0.0  0.00 3.083333
# 8     8     5 15.400 326.0000 299.5000 3.880000 3.370000 14.5500   0.0  1.00 6.000000

用法:

function getDataUri(url, callback) {
var image = new Image();

image.onload = function () {
    var canvas = document.createElement('canvas');
    canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size
    canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size

    canvas.getContext('2d').drawImage(this, 0, 0);

    // Get raw image data
    callback(canvas.toDataURL('image/png').replace(/^data:image\/(png|jpg);base64,/, ''));

    // ... or get as Data URI
    callback(canvas.toDataURL('image/png'));
};

image.src = url;
}

您也可以将此定义为承诺而非回电。

最后,getDataUri($scope.facebookUserPicture.url, function(dataUri) { // here you can set it up as the img src for the profile picture $scope.profilePictureUri = dataUri; });

Read more on this wonderful article by David Walash

答案 2 :(得分:1)

这会将任何资源作为blob获取,并使用filereader将其转换为base64数据网址。如果你在哪里使用canvas#toDataURL你就不会得到相同的base64 ...

var blob = new Blob(['Simulate a url'])
var url = URL.createObjectURL(blob)
console.log("original blob size", blob.size)

fetch(url)
.then(res => res.blob())
.then(blob => {
  var fr = new FileReader()
  fr.onload = () => {
    var b64 = fr.result
    console.log(b64)
    console.log("base64 size: ", b64.length)
    $iframe.src = b64
  }
  fr.readAsDataURL(blob)
})
<iframe id="$iframe"></iframe>

有更好的方法可以解决这个问题,那就是以某种方式将原始二进制文件存储为blob。 Base64将占用大约3倍的数据,因为javascript字符串是utf16,它将占用2倍的内存......

一些好的改进是indexedDB和Sandboxed Filesystem API