Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resize and/or crop images? #65

Open
gbouteiller opened this issue Jul 14, 2018 · 7 comments
Open

Resize and/or crop images? #65

gbouteiller opened this issue Jul 14, 2018 · 7 comments

Comments

@gbouteiller
Copy link

Is it possible to use this loader to also resize/crop images? For instance, it could be great to use it to create thumbnails with different ratio, ...
Thank you

@Melzmr
Copy link

Melzmr commented Aug 25, 2018

@gbouteiller – Yes, you can resize and crop images using sharp adapter.

@obennaci
Copy link

obennaci commented Oct 4, 2018

@Melzmr Can't figure out how to achieve that, can you share a snippet perhaps?

@AndrewIngram
Copy link

@Melzmr I think @gbouteiller was looking for ways to specify crop parameters at the URI-level. eg if I have a responsive background image in a hero section, I want to the height to be fixed as I generate crops of different widths.

@crucialfelix
Copy link

So sharp has params for height and crop strategy, but responsive-loader only takes width at the moment.

I guess it's possible to supply our own adapter, copying this one: https://github.com/herrstucki/responsive-loader/blob/master/src/adapters/sharp.js

and then including all the args to sharp.resize there (width, height, crop)

One strategy would be to use the width param as an integer key:

require("./images/image.jpg?resize?width=1")

that specifies one of a variety of settings used in our own site:

options = [
   {width: 1200, height: 800, fit: "crop"},
   {width: 300, height: 400, fit: "cover"},
]

which then calls:

image.clone.resize(options[width])

a la http://sharp.dimens.io/en/stable/api-resize/#parameters

@jstcki
Copy link
Contributor

jstcki commented Feb 12, 2019

See #70 (comment)

@crucialfelix
Copy link

Here is my "works today" solution. It's somewhat of a hack (using the width parameter as an index into some presets), but it will work until there is a better way to do this.

I'm using this with

// ./lib/sharp-adapter.js
const sharp = require("sharp");

/**
 * Factory to make a sharp adapter function for use in response-loader.
 * Width is interpreted as an integer index into the presets list supplied to the factory function.
 *
 * Usage:
 *
 * next.config.js
 *
 * const resizeOptions = {
 *   1: {
 *     width: 1024,
 *     height: 682,
 *     fit: "cover"
 *   },
 *   2: {
 *     width: 496,
 *     height: 593,
 *     fit: "cover"
 *   }
 * };
 *
 * // make the adapter
 * adapter: require("./lib/sharp-adapter")(resizeOptions)
 *
 * // usage
 * const main = require(`./images/some-image.jpg?resize&sizes[]=1`);
 * const thumb = require(`./images/some-image.jpg?resize&sizes[]=2`);
 */
function adapterFactory(resizeOptions) {
  return imagePath => {
    const image = sharp(imagePath);

    return {
      metadata: () => image.metadata(),
      resize: ({ width, mime, options }) =>
        new Promise((resolve, reject) => {
          const resizeOpts = resizeOptions[width] || { width: width };
          // console.log(width, mime, options, resizeOpts);

          let resized = image.clone().resize(resizeOpts);

          if (options.background) {
            resized = resized.background(options.background).flatten();
          }

          if (mime === "image/jpeg") {
            resized = resized.jpeg({
              quality: options.quality
            });
          }

          resized.toBuffer((err, data, { height }) => {
            if (err) {
              reject(err);
            } else {
              resolve({
                data,
                width: resizeOpts.width,
                height: height
              });
            }
          });
        })
    };
  };
}

module.exports = adapterFactory;

@strarsis
Copy link

strarsis commented Apr 6, 2019

+1, I also need this! I want to pass the height / crop width/height via URL, like
background: url('../images/background.jpg?height=1000.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants