0

before i post my question you have to now that i'm new at using node.js.

So i'm buillding an image uploader using express, fs and easyimage and it's works fine. I want to show the final resized dynamic image in the client side (views) using jade.

This is my routes images.js file:

var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res) {
res.send('home');
});

router.get('/upload', function(req, res) {
 res.sendfile("./public/html/images-upload.html");
});

 router.post('/upload', function(req, res) {

  var multiparty = require("multiparty");
  var form = new multiparty.Form();

 form.parse(req, function(err,fields,files){

  var img = files.images[0];
  var fs = require("fs");
  var easyimg = require("easyimage");


fs.readFile(img.path, function(err, data){

    var path = "./public/images/"+img.originalFilename;


    easyimg.rescrop({

     src:"public/images/"+img.originalFilename,       dst:"public/uploads/"+img.originalFilename,
    width:150, height:150,
    cropwidth:128, cropheight:128,
    x:0, y:0
    }).then(

    function(image) {

         console.log('Resized and cropped: ' + image.width + 'image.height);
          },
    function (err) {

     console.log(err);

    });


    fs.writeFile(path, data, function(error) {

    if(error) console.log(error);
        //controller

    var jade = require('jade');

        res.render('home', {templateRender: jade.renderFile})

        //template

    });


  });

   });

     });

      module.exports = router;
mscdex
  • 104,356
  • 15
  • 192
  • 153
Inati
  • 41
  • 1
  • 12

2 Answers2

0

In your index.jade file you need something like this:

extends layout

block content
  h1= title
  p This page will display a resized image.

  img(src='data:image/jpg;base64,#{buffer}')

Notice that that #{buffer} must be a base64-encoded String. Then in your request handler, you send the image like this

res.render('index', {title: 'Page Title', buffer: buffer2.toString('base64')})

You can convert your resized image to a Node buffer object. That is what 'buffer2' is in the above code. I've looked at the easyimage documentation and it appears that the success handler to resize functions may return a buffer, which can then be converted to a base64-encoded string. If you do not get a buffer object from easyimage you can experiment with other utilities. For example, can also try using the 'gm' utility which also utilizes ImageMagick. I learned the method for passing a base64 encoded object to Jade from this resource: https://blog.tompawlak.org/data-uri-scheme-image-nodejs-jade

Bob Cochran
  • 150
  • 2
  • 11
  • Hi Bob thank you for your replay, i tried but it seems to not work with easy image but its fin with 'gm'. Thanks a lot !! – Inati Feb 15 '16 at 08:57
  • You can read the file containing the resized image that has been processed by easyimage and display it like I show above, but 'gm' does seem to work better since it lets you have a buffer with the resized image all in one go. – Bob Cochran Feb 15 '16 at 12:36
  • I am trying to do the same in my case and I get this on the rendered html page Could not show image while this s what the gm code looks like let data = new Buffer(buffer).toString('base64') res.render('image', {title: 'Generated Image', source: data}) – PirateApp Mar 17 '17 at 06:27
0

First you need to setup your views engine to use jade:

// view engine setup.
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

It's a good idea to have a base template and add blocks to it to allow embed content.

views/layout.jade

doctype html
html
  head
    title Super uploader APP
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    block content

views/images-upload.jade

extends layout

block content
  form(method='post', action='/upload', enctype='multipart/form-data')
    input(type='file', name='images', accept='image/*', multiple)
    button(type='submit') Upload

  if img
    img(src='#{img.URL}', alt='None to show :(')

And finally your router.post method:

router.post('/upload', function(req, res) {
  var multiparty = require("multiparty");
  var form = new multiparty.Form();

  form.parse(req, function(err, fields, filesDict){
    var img = filesDict.images[0];
    var fs = require("fs");
    var easyimg = require("easyimage");

    easyimg.rescrop({
      src: img.path, // It's a temporal image, somewhere in /tmp, console.log('Image temp file', img.path);
      dst: "public/uploads/" + img.originalFilename,
      width: 150, height:150,
      cropwidth: 128, cropheight: 128,
      x:0, y:0
    }).then(function(image) {
        // see this:
        //   http://stackoverflow.com/questions/10729276/how-can-i-get-the-full-object-in-node-js-console-log-rather-than-object
        var util = require('util');
        console.log('Resized and cropped: ' + util.inspect(image, {showHidden: false, depth: null}));
        // drop leading "public" word from path.
        var url = image.path.substring(image.path.indexOf('/'), image.path.length);

        // Render images-upload.jade template with image URL passed as context.
        res.render('images-upload', {img: {URL: url}}); // will infer and search the images-upload.jade template
      },
      function (err) {
        console.log('Err', err);
      });
  });

});

As you can see, there's no need to reread the file after rescrop promise is resolved.

slackmart
  • 4,754
  • 3
  • 25
  • 39
  • Hi slackmart, original method and really interesting !! its workd perfectly!! Thank you !! – Inati Feb 15 '16 at 08:59