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

[gatsby-transformer-sharp] Resizing images to smallest of width or height without cropping or stretching #15573

Closed
GriffinJohnston opened this issue Jul 9, 2019 · 9 comments

Comments

@GriffinJohnston
Copy link

GriffinJohnston commented Jul 9, 2019

I would like to be able to use gatsby-transformer-sharp to create images that are resized such that:

  1. They maintain their original aspect ratio.
  2. The image is as large as possible without the height or width exceeding the provided height or width (or maxHeight/maxWidth) values.
  3. No cropping. No "letterboxing". No stretching.

I've beat my head against this for some time assuming that this very normal requirement would be a simple thing, but after digging, it seems like this is currently impossible.

So my question is twofold:

  1. Am I missing something? Is there some way to do this?
  2. If this is impossible — why? This seems like a significant omission, and Sharp has this capability. See the inside method of resizing: https://sharp.dimens.io/en/stable/api-resize/

I'd be happy to try my hand at updating this, but I just wanted to put feelers out there and see if there was a good reason this wasn't implemented already.

Why do we want this:
Let's say we have a website for an art auction service. We have gallery pages with large numbers of images of completely unpredictable size and aspect ratio. Some are tall and narrow, some wide and short, some square. We need to be able to create different versions of those images (for say, thumbnails, expanded popups, etc.) that are never taller than n pixels, and never wider than n pixels. We absolutely cannot crop or stretch these images, however. Artists are very particular about how their work is presented.

Hopefully that helps illustrate the problem. Thanks ahead of time!

@cseebach-tpc
Copy link

It should be possible to do this in a combination of CSS and Gatsby - you can retrieve the aspectRatio of a particular image, and then apply one of these CSS styles based on the result:

query AllSitePageData {
  allImageSharp {
    edges {
      node {
        sizes {
          aspectRatio
        }
      }
    }
  }
}
.full-width {
  width: 100%
}

.full-height {
  height: 100% 
}

The simplest case would be when you have a square container and you don't want the image to exceed those boundaries - your condition would be if(aspectRatio > 1)

@cseebach-tpc
Copy link

I think I've got some details wrong - my CSS is always improving as I go - but maybe this can point you in the general direction?

@GriffinJohnston
Copy link
Author

GriffinJohnston commented Jul 10, 2019

Thanks for the reply! So yea, this can be easily accomplished with css of course — but the point of using things like gatsby-transformer-sharp is to create appropriately-sized images for a given context, which saves bandwidth and improves page-load times.

@cseebach-tpc
Copy link

You still get the benefit of the appropriately sized images when you use the techniques in combination - they only load in on scroll if you've got that configured, and I'm fairly certain the srcset attribute will still pick the right image for the final size of the image on the page. But I understand your desire for a more built-in solution.

@GriffinJohnston
Copy link
Author

GriffinJohnston commented Jul 10, 2019

I think maybe I haven't explained the issue well. I'll try to illustrate more clearly:

I have two images.

  • Image A is 1000px by 200px (wide and short)
  • Image B is 300px by 1500px (narrow and tall)

I would like to apply a rule that resizes each of these images so that they are no more than 500px wide, and no more than 500px high, while maintaining the original aspect ratio.

If I apply that rule to my two images, I will get the following:

  • Image A is now 500px by 100px
  • Image B is now 100px by 500px

Both have maintained their aspect ratios, and haven't been cropped, but are resized to fit a maximum height and width.

Currently gatsby-transformer-sharp doesn't support this. All I can do is set a width or maxWidth, which doesn't help me for images that are narrow and tall.

@cseebach-tpc
Copy link

Thanks for the concrete example - I should note that I'm not a Gatsby author or committer, just an interested bystander, so my opinion doesn't mean a whole lot.

If it's something you really want to build, I encourage you to spin up a repo and tackle the issue. The community is vibrant because of your energy and the energy of those like you! ❤️

If you need this image feature for a site you're currently building, you'll find it much faster to use multiple ImageSharp GraphQL queries and then choose which image to put on the page based on the aspect ratio of the original.

Here would be an example query, can drop it anywhere you're using a childImageSharp query.

childImageSharp {
  setWidth: fixed(width: 500) {
    ...GatsbyImageSharpFixed
  }
  setHeight: fixed(height: 500) {
    ...GatsbyImageSharpFixed
  }
}

@GriffinJohnston
Copy link
Author

GriffinJohnston commented Jul 10, 2019

Thanks for the suggestion! That definitely works. The only issue here is that you end up generating a bunch of extra unused images.

In any case I'm happy to take a crack at updating this when I get a moment, but I guess I wanted to see if this was left out of the plugin for a good reason.

@missmatsuko
Copy link
Contributor

This open PR might address this issue:
#14852

@GriffinJohnston
Copy link
Author

GriffinJohnston commented Jul 17, 2019

@missmatsuko Thank you! That absolutely addresses my issue. Sorry I wasn't able to find that before and posted a duplicate issue!

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

3 participants