在Node JS中裁剪个人资料图片

时间:2016-02-14 02:41:31

标签: javascript node.js

我希望我网站上的用户能够裁剪他们将用作个人资料图片的图片。然后,我想将此图像存储在我服务器上的uploads文件夹中。

我使用php和JCrop插件完成了这项工作,但我最近开始更改我的网站框架以使用Node JS。

这是我允许用户在使用JCrop之前裁剪图像的方法:

 $("#previewSub").Jcrop({
     onChange: showPreview,
     onSelect: showPreview,
     aspectRatio: 1, 
     setSelect: [0,imgwidth+180,0,0],
     minSize: [90,90],
     addClass: 'jcrop-light' 
     }, function () {
         JcropAPI = this;
     });

我会用php将它存储在一个文件夹中:

<?php

$targ_w = $targ_h = 300;
$jpeg_quality = 90;

$img_r = imagecreatefromjpeg($_FILES['afile']['tmp_name']);
$dst_r = ImageCreateTrueColor( $targ_w, $targ_h );

imagecopyresampled($dst_r,$img_r,0,0,$_POST['x'],$_POST['y'],
$targ_w,$targ_h,$_POST['w'],$_POST['h']);

header("Content-type: image/jpeg");
imagejpeg($dst_r,'uploads/sample3.jpg', $jpeg_quality);
?>

如上所示,使用Node JS是否有一个等效的JCrop插件?可能有多个,如果有,你会推荐什么?任何简单的例子也都很受欢迎。

修改

因为问题没有得到任何答案,也许有可能将JCrop代码保留在上面,并且可能将我的PHP代码更改为Node JS。如果这是可能的,有人可以告诉我如何翻译我的PHP代码,相当于上面的PHP会是什么?

我是Node的新手,所以我很难找到等效的功能而不是。

2 个答案:

答案 0 :(得分:2)

您可以发送原始图像(原始用户输入文件)和JCrop的裁剪参数结果。 发送en64ded in base64(string)的图像,当服务器收到它时将其存储为Buffer:

var img = new Buffer(img_string, 'base64');

ImageMagick文档:http://www.imagemagick.org/Usage/files/#inline内联:使用base64)

然后服务器将图像放在缓冲区和裁剪参数中 从那里你可以使用类似的东西:
https://github.com/aheckmann/gm
...或...... https://github.com/rsms/node-imagemagick
将修改强制转换为缓冲区映像,然后将结果存储在文件系统中。

您还有其他选项,例如在客户端操作它并发送裁剪的编码图像结果。

编辑:首先尝试阅读&amp;用户使用输入时对图像进行编码:

$('body').on("change", "input#selectImage", function(){readImage(this);});
function readImage(input) {
    if ( input.files && input.files[0] ) {
        var FR = new FileReader();
        FR.onload = function(e) {
            console.log(e.target.result);
            // Display in <img> using the b64 string as src
            $('#uploadPreview').attr( "src", e.target.result );
            // Send the encoded image to the server
            socket.emit('upload_pic', e.target.result);
        };       
        FR.readAsDataURL( input.files[0] );
    }
}

然后,当在服务器上收到时,使用上面提到的Buffer

var matches = img.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/), response = {};
if (matches.length !== 3) {/*invalid string!*/}
else{
  var filename = 'filename';
  var file_ext = '.png';
  response.type = matches[1];
  response.data = new Buffer(matches[2], 'base64');
  var saveFileAs = 'storage-directory/'+ filename + file_ext;
  fs.unlink(saveFileAs, function() {
    fs.writeFile(saveFileAs, response.data, function(err) {if(err) { /* error saving image */}});
  });
}

我个人在客户端编辑后发送编码图像。
服务器只需验证并保存文件,让客户端完成额外的工作。

答案 1 :(得分:2)

正如所承诺的,以下是我在Express个项目中使用darkroom.js的方法。

//Location to store the image
var multerUploads = multer({ dest: './uploads/' });

我首先上传图片,然后允许用户裁剪。这是因为,我想保留原始图像,下面的上传玉:

form(method='post', action='/user/image/submit', enctype='multipart/form-data')
   input(type='hidden', name='refNumber', value='#{refNumber}')
   input(type='file', name='photograph' accept='image/jpeg,image/png')
   br
   input(type='submit', value='Upload image', data-role='button')

enter image description here

以下是我用来裁剪图片的表单

//- figure needed for darkroom.js
figure(class='image-container', id='imageContainer')
  //specify source from where it should load the uploaded image
  img(class='targetImg img-responsive', src='/user/image/view/#{photoName}', id='target')
form(name='croppedImageForm', method='post', enctype='multipart/form-data', id='croppedImageForm')
  input(type='hidden', name='refNumber', id='refNumber', value='#{refNumber}')
  input(type='hidden', id='encodedImageValue', name='croppedImage')
  br
  input(type='submit', value='Upload Cropped Image', id='submitCroppedImage' data-role='button')

enter image description here

使用此javascript将darkroom.js附加到figure元素。

new Darkroom('#target', {
      // Canvas initialization size
      minWidth: 160,
      minHeight: 160,
      maxWidth: 900,
      maxHeight: 900,
    });
  });

按照步骤1,步骤2和最后的步骤3,裁剪区域的base64值存储在figure元素下,请参阅下面屏幕截图中显示的控制台日志:

enter image description here

然后我点击了上传裁剪图片时触发的javascript,然后将img的base64值从figure复制/粘贴到id为encodedImageValue的input元素然后将其提交给服务器。 javascript函数如下:

$("#submitCroppedImage").click(function() {
    var img = $('#imageContainer img');
    var imgSrc = img.attr('src');

    if(imgSrc !== undefined && imgSrc.indexOf('base64') > 0) {
      $('#encodedImageValue').val(img.attr('src'));
      $.ajax({
        type: "POST",
        url: "/user/image/cropped/submit",
        data: $('#croppedImageForm').serialize(),
        success: function(res, status, xhr) {
          alert('The CROPPED image is UPLOADED.');
        },
        error: function(xhr, err) {
          console.log('There was some error.');
        }
      });
    } else {
      alert('Please follow the steps correctly.');
    }
  });

以下是以POST字段为主体的base64请求的屏幕截图

enter image description here

post请求映射到Express app中的以下路由处理程序:

router.post('/user/image/cropped/submit', 
     multerUploads, 
    function(req, res) {

  var photoName = null;
  var refNumber = req.body.refNumber;

  var base64Data = req.body.croppedImage.replace(/^data:image\/png;base64,/, "");

  fs.writeFile("./uploads/cropped-" + 'profile_image.png', base64Data, 'base64',
        function(err) {
          logger.info ("Saving image to disk ...");
          res.status(200).send();
      });
});

我有以下.js个文件与真棒Fabric.jsdarkroom.js

相关
script(src='/static/js/jquery.min.js')
script(src='/static/js/bootstrap.min.js')

//get the js files from darkroom.js github
script(src='/static/js/fabric.js')
script(src='/static/js/darkroom.js')
script(src='/static/js/plugins/darkroom.crop.js')
script(src='/static/js/plugins/darkroom.history.js')
script(src='/static/js/plugins/darkroom.save.js')

link(href='/static/css/darkroom.min.css', rel='stylesheet')
link(href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css', rel='stylesheet')
//get this from darkroom.js github
link(href='/static/css/page.css', rel='stylesheet')

最后,还要复制svg图标以进行选择,裁剪,保存等(来自darkroo.js github page)。