Closed johnridesabike closed 2 years ago
@johnridesabike, I don’t have a solution per se, just a thought that I’m currently working through as I familiarize myself with this plugin too. I’ve got an dev site that I’m experimenting with passing URLs from Cloudinary as the src
argument to Image(src)
using this plugin. Again, I don’t know if it meets your use case, but I think there’s some value in keeping this plugin as a slim build-time tool. Then, if you want more sophisticated image transformations, you could use a remote service (and, in that sense, the remote caching features come in really handy) or another package that’s designed for those tasks.
I'd also love the ability to crop just some of the given widths, to change the aspect ratio for mobile, for example.
@zachleat can we ask priority for this? E.g. think just a full screen hero background image optimization for mobiles, usually 800x1200, when we don't know the dimensions of the user selected picture (by some headless cms) but we need to resize it to be exactly 1200px height.
I'm working on a tiny Webpack image loader based on eleventy-img
(to reduce dependencies in my 11ty sites) which can be used in CSS like some.jpg?format=webp&height=1200
but currently only width
can be used. FYI currently I'm using webpack-image-resize-loader
(link) which is also using Sharp and can handle heights, but now it's an extra unnecessary dependency with a different version of Sharp. eleventy-img
could be used for this task so nicely...
Thank you!
I wonder if we can use sharpOptions: {}
to pass arguments to Sharp and define a shortcode that does cropping and aspect ratio
It seems to me that the sharpOptions
of eleventy-img
is for the Sharp constructor, and the resize parameters cannot be set there (fix me if I'm wrong).
However looking at the code of eleventy-img
where it does the resizing (L437) sharpInstance.resize(resizeOptions)
the resize options - what we would need to alter - are fixed.
Maybe a new option and a little modification something like this could work?:
let userSharpResizeOptions = this.options.sharpResizeOptions || {};
sharpInstance.resize({
resizeOptions,
...userSharpResizeOptions
});
...then we would be able to use all the magic of https://sharp.pixelplumbing.com/api-resize#parameters (but it's just a sudden idea)
Good eye! They are constructor options, I didn't notice that 😆
The name sharpResizeOptions
feels right to me too. But the codebase's way to do || {}
seems to be via Object.assign
So maybe Object.assign({}, resizeOptions, this.options.sharpResizeOptions)
? (I don't know how object.assign works, just writing this in hope some one will make a PR)
If someone does make a PR, please include the name in keysToKeep too
This was once started in May 2020, the PR is still open but abandoned. Even sharpResizeOptions
was recommended before in the last post. I don't know why this thing is still hanging 😞
@sprabowo are you still interested in 11ty? (seems to me he has switched to Astro)
Please consider this. Cropping images at build time seems so much better than just using CSS methods from a performance perspective.
The code has changed a lot since then, so I wouldn't really expect it to get merged. If there is no PR by Jan 1st, I'll draft one. Although I wouldn't expect it to be merged and shipped any time soon from that.
If you need the feature soon, I strongly recommend forking the repo and implementing sharpResizeOptions
yourself. Then after you've tested it, consider contributing the improvements back with a PR :)
Sure, I'm thinking of that, but also I'm absolutely certain that @zachleat could do this thing ways better than I could. I'm just a plain 11ty user and to be honest I would give my half hand for the JS skills that Zach has 😄 . Also as I read somewhere before, he said that issues with more likes will get more priority.
So if you are reading this, please press the like icon on the first post 👍 if you need this feature.
I believe this is the top feature request right now but it’s still going into the queue. Thanks folks!
This repository is now using lodash style issue management for enhancements. This means enhancement issues will now be closed instead of leaving them open.
View the enhancement backlog here. Don’t forget to upvote the top comment with 👍!
hmmm wonder if this kinda dies or somebody have a good idea to crop images ? custom sharp instead or
@mortendk I tend to use an external NPM script running in parallel to generate resized images. On bigger projects, I generally use external images services.
@mortendk I figured sharp could be a good workaround, here is the Shortcode I added to get responsive picture generation in templating. (I'm an absolute 11ty noob so it might be really dirty coding but it worked out for me)
const Image = require("@11ty/eleventy-img");
const Sharp = require('sharp');
module.exports = function(eleventyConfig) {
eleventyConfig.addShortcode("myImage", async function(src, alt, smallSize, midSize, bigSize) {
try {
console.log(`myImage shortcode called with src:`, src);
const resizedImageBuffer = await Promise.all([
resizeImage(src, smallSize[0], smallSize[1], "cover"),
resizeImage(src, midSize[0], midSize[1], "cover"),
resizeImage(src, bigSize[0], bigSize[1], "cover"),
]);
const metadata = await Promise.all(
resizedImageBuffer.map(async buffer => {
return await Image(buffer, {
formats: ["webp"],
outputDir: "./dist/assets/img/output",
urlPath: "/assets/img/output/",
});
})
);
console.log("Generated image metadata:", metadata);
let imageAttributes = {
alt,
loading: "lazy",
decoding: "async",
class: "o-fluidimage"
};
const imageHTML =
`<picture>
<source media="(min-width: 1050px)" srcset="${metadata[2].webp[0].url}">
<source media="(min-width: 750px)" srcset="${metadata[1].webp[0].url}">
<img
class="${ imageAttributes.class }"
alt="${ imageAttributes.alt }"
loading="${ imageAttributes.loading }
decoding="${ imageAttributes.decoding }"
src="${ metadata[0].webp[0].url }"
/>
</picture>`;
console.log(`Generated image HTML:`, imageHTML);
return imageHTML;
}
catch (error) {
console.error(`Error in myImage shortcode:`, error);
return "";
}
});
}
async function resizeImage(src, width, height, mode) {
return await Sharp(src)
.resize({ width: width, height: height, fit: mode })
.toBuffer();
}
I just started using this plugin, and this is the main feature I’m missing the most.
Its use case is when you need your images to conform to specific aspect ratios, such as square thumbnails.
(Sure, you can accomplish this with CSS too, but I’d prefer cropping the images during the build process.)
Since the
widths
option is already an array, perhaps there could be a singleaspectRatio
option too? e.g.[1, 1]
or[16, 9]
.Bonus points if you could also pass all of the sharp resize options too, e.g.
position: "center"
https://sharp.pixelplumbing.com/api-resize