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

Image resizing/cropping #1728

Closed
wants to merge 8 commits into from
Closed

Image resizing/cropping #1728

wants to merge 8 commits into from

Conversation

kujohn
Copy link
Contributor

@kujohn kujohn commented Dec 24, 2015

Looking for feedback on this image resizing/cropping feature #1014.

The image should sit right next to the markdown files with the syntax instruction based on this:

hero.w400-h500-c.jpg // crops image from the upper left
hero.h500.jpg // resize to height, keeping the original width

Example Usage:

Content Folder:
post/golang-tips.md
post/gopher.w400-c.jpg
Shortcode Usage:
{{ < resizedImage "gopher.jpg" > }}

The use of resizedImage shortcode is necessary to relatively reach the photo one folder back. It is due to how Page write destination is wrapped inside it's own folder.

Output Public Folder:
post/golang-tips/index.html
post/gopher.jpg

There's a few things I plan on implementing:

  • Image resize based on ratio
  • Image crop target (upper left, center, etc..)
  • Without the use of shortcode
  • Have the image sit right inside the post folder, next to index.html

Please provide feedback and guidance, happy holidays!

@spf13
Copy link
Contributor

spf13 commented Dec 24, 2015

This is fantastic work and very appreciated. I've been thinking a bit differently about the interface for it though.

It doesn't make a lot of sense to me to name the file on disk with the intended manipulations as it's pretty trivial anyway to do that when you put the file there.

The real benefit to this feature in my eyes is the ability for someone to specify those dimensions inside of the content and that triggers an additional version of the file to be created matching those dimensions.

so I put a single file...

post/gopher.jpg

then in a content or template file I would reference it...

{{ < resizedImage "gopher.h500.jpg" > }}

perhaps in a different file I reference it differently

{{ < resizedImage "gopher.w200-h300-c.jpg" > }}

This would result in all three versions of this file created in the destination.

post/gopher.jpg
post/gopher.h500.jpg
post/gopher.w200-h300-c.jpg

I think the real power of this feature is the ability for template designers and content creators to be able to dictate image dimensions without having to worry about manipulating images.

Does that make sense?

Other than that I think this looks good. I support using rez for the resizing.

Another idea that I've been thinking about a lot lately would be a notion of caching or avoiding unnecessary work. There's a lot of expensive operations that we needlessly do over and over today. Every call to asciidoctor could benefit significantly from caching. Image manipulations would as well.

It would be ideal to have a single caching system rather than reinvent it for each component of Hugo.

@spf13
Copy link
Contributor

spf13 commented Dec 24, 2015

also join us on gitter (gitter.im/spf13/hugo) if you want to chat about any of the dev you are doing. We're a friendly bunch and happy to give advice or answer questions.

@kujohn
Copy link
Contributor Author

kujohn commented Dec 25, 2015

Thanks for the feedback @spf13, that makes better sense to have the manipulation interface in shortcodes. Theme creators can rely and utilize images and specify their size. There could also be shortcodes in the future to generate thumbnail galleries based on this interface.

I'll will give it a shot on implementing this and look into some type of caching. Thanks for the gitter tip as well!

@spf13 spf13 changed the title Devel/1014 image resizing/cropping Jan 4, 2016
@rdwatters
Copy link
Contributor

Would it make more sense to centralize images in /static/images/instead of keeping images within the folder for a particular article? I could see this being easier to manage in terms of thumbnails (eg, with list views), and especially in sites where an image is going to be used more than once (I feel like this happens all the time, since images should only be added when enhancing content). Would a structure like the following be easier to buildout and include in the config file for the site?

static
   /images
     myphoto1.jpg
     myphoto2.jpg
     myphoto3.jpg
     /200x200
      myphoto1.jpg
      myphoto2.jpg
      myphoto3.jpg
     /100x100
      myphoto1.jpg
      myphoto2.jpg
      myphoto3.jpg
     /authors
      author1.jpg
      author2.jpg
      author3.jpg
        /200X200
        author1.jpg
        author2.jpg
        author3.jpg
        /100x100
        author1.jpg
        author2.jpg
        author3.jpg

And then have this set in the config to create on build...

#config.yaml
resizeImages: true
imageSizes:
  - 200X200
  - 100X100

Here are a few ideas of why this might help, in order of most to least important

  1. Doesn't add unnecessary presentational information to markdown...for those of us who love markdown because it works with any/all SSGs
  2. Centralizes assets (ie, with a "master copy" of the original images in the top of the static folder for easier management).
  3. (This really relates to 2) The ability to associate images,when appropriate, in the yaml/json/toml for a file and then include it in templating logic more easily across the site. E.g. -
---
title: My Name is Ryan Watters
main_image: author1.jpg
main_image_description: This is a photo of author Ryan Watters
description: Yada yada yada yada yada yada
---

And then something to the effect of the following in the templating logic for authors/single.html.

<article>
   <header>
   <h1>{{.Title}}</h1>
   <img src="{{.Site.BaseURL}}/{{.Section}}/200x200/{{.Params.main_image}}}" alt="{{.Params.main_image_description}}">
   </header>
...

Or whatever, I think you see what I mean. Then use that same idea of thumbs in list pages. Ultimately, Hugo will never replace a full-blown DAM. I get the feeling this might be too opinionated since the docs are very clear that Hugo has no opinions about how a person structures his/her content. Thoughts @spf13 @kujohn ?

@spf13
Copy link
Contributor

spf13 commented Jan 7, 2016

@rdwatters I think your solution makes sense, but would really just be a separate process. That would be something very easily added independent of hugo. The solution I've proposed is an integrated solution as by enabling content creators and template designers to declare size it requires a deeper level of integration that could only be done by Hugo.

If we do implement your solution I think it's independent of this one, and really falls more into a DAM territory.

@kujohn kujohn changed the title image resizing/cropping Image resizing/cropping Jan 8, 2016
@rdwatters
Copy link
Contributor

@spf13 I see what you're saying. I have mixed feelings about the shortcodes. Yes, they make it easier to write more with less in markdown, but at the same time, they run the risk of muddying separation of concerns.

The thing I love about SSGs is that I can write to any .md file with yaml as the front matter and easily import it into Jekyll, Hugo, Hexo, Middleman, etc without having to ever touch the content, run scripts, or even know any programming, really. I'm firm on this with the people on my team: never, never fiddle with the .md for the sake of visual design. That said, a shortcode is prettier than a full iFrame from YouTube, and as long as they stay consistent, at least I can script them in node or bash.

Thanks for this amazing tool. Everyone I've turned on to Hugo has definitely had their hair blown back. Cheers.

@bep
Copy link
Member

bep commented Jan 12, 2016

I'm firm on this with the people on my team: never, never fiddle with the .md for the sake of visual design.

I kind of agree -- but not with the "you have to configure the sizes in config.toml etc.". I would like a feature that signals to Hugo that I want a different size. If we hook this into the transformer chain that does link manipulation, this should be pretty cheap too (as in: we don't need another pass and the image processing can be executed in full throttle on all cores):

  • For all local image refs:
    • Does it contain a "size indicator"
    • Does that file exist in /static or /content (??) (or have we already handled this image)
  • If not: Create it (directly into the destination? cache ...)

I haven't thought hard on this, but I agree with @spf13 that I would prefer convention before configuration on this.

@spf13
Copy link
Contributor

spf13 commented Jan 13, 2016

In agreement with @bep.

A proper implementation in my eyes is one where the theme designer can specify dimensions as well as the content creator as a natural part of their workflow and Hugo just works.

What if inline in the markdown I referenced this image.

hero.w400-h500-c.jpg and Hugo just knew that I meant to resize the image (hero.jpg) and crop it. Heck it could even keep that exact same url intact and just put it there. No rewriting of the html needed.

I'll leave it up to the implementor to determine if the most efficient way to accomplish this is via short code or inline parsing of the content (or both).

@rdwatters
Copy link
Contributor

@bep Ah, yes, I see. Can't believe I got slapped with the CB4C hand. I should know better.

I guess my thought (since I'm not a golang programmer) was that somehow adding dimensions to the config would make the resizing less expensive.

@spf13, so the output HTML (ie, taking your example) would still look like...

<img src="/images/hero.w400-h500-c.jpg alt="Riveting photo of Bonnie Tyler in 1986"/>

And the markdown as follows...

![Riveting photo of Bonnie Tyler in 1986](/images/hero.w400-h500-c.jpg)

And the static folder as....

hugo-site/
  static/
    images/
       hero.jpg
       hero.w400-h500-c.jpg

After the resizing has been run?

@kujohn I feel like I'm speaking out of turn on these suggestions since you're the one doing all the heavy lifting. Are these approaches in conflict with what you've already worked on?

@spf13
Copy link
Contributor

spf13 commented Jan 13, 2016

Yes, something along like that. I do want to avoid using static for this
though.

The initial idea behind static was that files are placed there that won't
be touched at all by Hugo.

I've been thinking through two potential solutions for this.

One is fairly straightforward. A new directory called assets for things to
be processed (images, scss, etc)

The other idea is a new approach to content where a directory represents a
post and can contain media along side it.

I'm not altogether against static either as we technically aren't modifying
the original (like we would be with scss).

The right answer is likely a combination of these approaches (using our
layered approach as we already do with the themes)
On Tue, Jan 12, 2016 at 10:43 PM Ryan Watters notifications@github.com
wrote:

@bep https://github.com/bep Ah, yes, I see. Can't believe I got slapped
with the CB4C hand. I should know better.

I guess my thought (since I'm not a golang programmer) was that somehow
adding dimensions to the config would make the resizing less expensive.

@spf13 https://github.com/spf13, so the output HTML (ie, taking your
example) would still look like...

<img src="/images/hero.w400-h500-c.jpg alt="Riveting photo of Bonnie Tyler in 1986"/>

And the markdown as follows...

Riveting photo of Bonnie Tyler in 1986

And the static folder as....

hugo-site/
static/
images/
hero.jpg
hero.w400-h500-c.jpg

After the resizing has been run?


Reply to this email directly or view it on GitHub
#1728 (comment).

@rdwatters
Copy link
Contributor

@spf Hmmm. So...

<--/content/articles/my-article-name.md-->
![Riveting photo of Bonnier Tyler](hero.w400-h500-c.jpg)
<!--http://mysite.com/articles/my-article-name/-->
<img src="hero.w400-h500-c.jpg/ alt="Riveting photo of Bonnier Tyler">
//AFTER BUILD
mysite/
  articles/
    my-article-name/
      index.html
      hero.w400-h500-c.jpg

//DIRECTORIES IN DEV
mysite/
  content/
    articles/    
  static/
    images/
      hero.jpg

assets/ works too, but is the goal to replace other SCSS processors, JS concat/minifiers, etc? I'm already using an assets folder in my little playground site that I'm moving from Jekyll to Hugo just to learn both SSGs. Just pushed that repo here.

@bep
Copy link
Member

bep commented Jan 13, 2016

The other idea is a new approach to content where a directory represents a post and can contain media along side it.

Many people would want this, but I think what we are talking about now should work for "both". As to the assets pipeline, this is a concept we don't have yet.

I think the main issue here is:

These are build products and should not live inside my Git repo.

The above may be true for LESS and CSS files, too, but less obvious.

So without caching, Hugo could write them directly to /public (or whatever the destination is). But since this is a potentially expensive operation, we should store them in /temp and only do a rebuild for the changed images.

@kujohn
Copy link
Contributor Author

kujohn commented Jan 14, 2016

@rdwatters No worries, I think the work for parsing filename props and transforming of images can be carried over to what we ultimately decide to do. I haven't done any additional commits besides that. Thanks for asking! :)

I think if we had an asset pipeline, that would be the perfect home for image transformation. But like what @bep said, it doesn't exist yet. I could give it a shot (with advisors and pointers) to try implementing an asset pipeline for image first. But I get the feeling that I may be too green to hugo's internals.

In terms of image location, having them along side the post in a directory seems less of a mental overhead for the user. If we're using a central assets folder for thousands of posts, it could be tricky for users to come up with non-colliding filename. Whereas image in the post directory would allow users to drag images in and use them as is.

we should store them in /temp and only do a rebuild for the changed images.

Any tips on where /temp is being used in the hugo codebase?

@bep
Copy link
Member

bep commented Jan 14, 2016

Any tips on where /temp is being used in the hugo codebase?

We use it for the remote files cache and the Highlight cache, but we should clean up that thought, maybe ..

@bep
Copy link
Member

bep commented Jun 26, 2017

I'm sorry that I have not followed up on these old pull requests. I appreciate the work put into this, but we will in the near future introduce "resource bundles" in Hugo, where this feature will fit more naturally in.

@bep bep closed this Jun 26, 2017
@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 11, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants