Image EXIF orientation

Hi,

how can I determine which EXIF orientation a photo has? I have various photos in a directory with different orientations (portrait, landscape). I want to automatically align and adjust the size. Resizing works. I just can’t do the turning. Below a photo with my result, the shortcode itself and the shortcode call in an .md file. Can somebody help me with it?

Hugo Static Site Generator v0.62.2/extended darwin/amd64 BuildDate: unknown

Frank

Shortcode gallerie.html

{{ with .Get "title" }}
  <h2>{{ . }}</h2>
{{ end }}
  <div class="gallery" itemscope itemtype="http://schema.org/ImageGallery">
  {{/*  {{ range (.Page.Resources.Match (printf "%s*" (.Get "folder"))) }}  */}}
  {{ range .Page.Resources.Match "gallery/*" }}
    {{ $resource := .Permalink }}
    {{ $thumbnail := .Resize "250x" }}
    <figure itemscope itemtype="http://schema.org/ImageObject" class="image gallery-item">
    <a href="{{ .Permalink }}" itemprop="contentUrl" data-size="{{ .Width }}x{{ .Height }}" >
      <img src="{{ $thumbnail.Permalink }}" itemprop="thumbnail" alt="{{ .Params.alt }}" class="galleryImage" />
    </a>
    <figcaption itemprop="caption description">
      {{ .Params.caption }}
      <span itemprop="copyrightHolder">{{ .Params.copyright }}</span>
    </figcaption>
    </figure> 
  {{ end }}
  </div>

shortcode call in the .md-File

{{< gallerie folder=“gallery” title=“eine überschrift” >}}

Can you provide me with a snippet of source code for asking if the picture was taken in portrait mode?
https://www.impulseadventure.com/photo/exif-orientation.html - Don’t understand how to query it.

So, I have an open issue about “auto rotation” based on exif. But time is scarce …

I guess it should be possible to look into $image.Exif and find the exif tag for this, but don’t ask me for the details …

It is clear to me that I can rotate the photos manually beforehand. But I don’t want that, it should be recognized and rotated automatically. The user should not worry about it and simply upload his photos to the “gallery” directory. But since I cannot see whether the photo is in portrait or landscape format, I cannot work with rotate (r90).

The following source also did not recognize which format is available:

{{ with .Get "title" }}
  <h2>{{ . }}</h2>
{{ end }}
  <div class="gallery" itemscope itemtype="http://schema.org/ImageGallery">
  {{/*  {{ range (.Page.Resources.Match (printf "%s*" (.Get "folder"))) }}  */}}
  {{ range .Page.Resources.Match "gallery/*" }}
    {{ $resource := .Permalink }}
    
    {{ $thumbnail := . }}
    {{ $orientation := cond (ge $thumbnail.Width $thumbnail.Height) "landscape" "portrait" }}
    {{ if eq $orientation "portrait" }}
    {{ $thumbnail := .Resize "x250" }}
    {{ else }}
      {{ $thumbnail := .Resize "250x" }}
    {{ end }}
    <figure itemscope itemtype="http://schema.org/ImageObject" class="image gallery-item">
    <a href="{{ .Permalink }}" itemprop="contentUrl" data-size="{{ .Width }}x{{ .Height }}" >
      <img src="{{ $thumbnail.Permalink }}" itemprop="thumbnail" alt="{{ .Params.alt }}" class="galleryImage" />
    </a>
    <figcaption itemprop="caption description">
      {{ .Params.caption }}
      <span itemprop="copyrightHolder">
        {{ .Params.copyright }}
        {{ if eq $orientation "portrait" }}
        {{ $orientation }}-portrait
        {{ else }}
        {{ $orientation }}-Landscape
        {{ end }}
      </span>
    </figcaption>
    </figure>  
  {{ end }}
  </div>

Hi!

You will have to check the value of the $photo.Exif.Tags.Orientation to determine which way the photo needs to be rotated. The link provided by @b_rad shows how the values of the .Orientation field relate to the spacial orientation of the image:

Using this, you can write a snippet that can rotate the image based on the .Oritientation value:

{{ with $photo }}
    {{ $orientation = .Exif.Tags.Orientation }}
    {{ if eq $orientation 1 }}
      // Do nothing, image is right-side up
    {{ else if (eq $orientation 8) }}
      // Rotate the image 90deg CCW (.Resize "r90")
     ... so on
    {{ end }}
{{ end }}
5 Likes

Today I learned ^

@setphen
Thanks for your help, unfortunately this doesn’t work for me. What am I doing wrong?

{{ with .Get "title" }}
  <h2>{{ . }}</h2>
{{ end }}
<div class="gallery" itemscope itemtype="http://schema.org/ImageGallery">
  {{/*  {{ range (.Page.Resources.Match (printf "%s*" (.Get "folder"))) }}  */}}
  {{ range .Page.Resources.Match "gallery/*" }}
    {{ $resource := .Permalink }}
    
    {{ $thumbnail := . }}
    {{ with $thumbnail }}
      {{ $orientation := .Exif.Tags.Orientation }}
    {{ end }}

ERROR 2020/01/21 08:29:00 Rebuild failed:

ERROR 2020/01/21 08:29:00 “/Users/frank/…/hugo-projects/ombud/content/blog/post2/index.md:22:1”: failed to render shortcode “gallerie”: failed to process shortcode: “/Users/frank/…/hugo-projects/ombud/themes/verein/layouts/shortcodes/gallerie.html:12:30”: execute of template failed: template: shortcodes/gallerie.html:12:30: executing “shortcodes/gallerie.html” at <.Exif.Tags.Orientation>: nil pointer evaluating *exif.Exif.Tags

I suspect that you have some images without Exif (or that Hugo failed to read it for some reason).

I suggest you rewrite it to somthing like this:

{{ with $photo }}
{ { $orientation := 1 }}
{{ with .Exif }}
{{ $orientation = .Tags.Orientation }}
{{ end }}
{{ end }}
2 Likes

@bep
You were right, the EXIF data of the pictures was broken. I do not need to rotate the pictures because they are automatically displayed correctly. What an effort, but it does. Thank you for your help and for your working time that you are investing in the Hugo project.

Thanks for all other comments.

I got the original source code from Bruno Amaral: https://brunoamaral.eu/post/creating-a-gallery-component-for-the-hugo-static-site-generator/ - very interesting article.

For documentation purposes, the source code I have below:

Content structure:

content
   blog
      <blogpost title>
          gallery
             picture01.jpg
             picture02.jpg
          index.md

Shortcode call in index.md:

{{<gallery folder="gallery/*" title="Gallery Title>}}

Shortcode source:

I want to display 3 photos side by side. My content area is 1100px wide on the desktop. 1100/3 = 366px. Since I add a space for the photos, 365px is enough for a normal screen. For high-resolution Apple devices, the whole thing has to be doubled: 365px * 2 = 730px. The area around the image tag could be optimized in the code. This would deliver 365px for normal devices and 730px for high-resolution devices.

{{ with .Get "title" }}
  <h2>{{ . }}</h2>
{{ end }}
<div class="gallery" itemscope itemtype="http://schema.org/ImageGallery">
  {{ range (.Page.Resources.Match (printf "%s*" (.Get "folder"))) }}

    {{ $resource := .Permalink }}
    {{ $thumbnail := .Resize "730x" }}
    <figure itemscope itemtype="http://schema.org/ImageObject" class="image gallery-item">
    <a href="{{ .Permalink }}" itemprop="contentUrl" data-size="{{ .Width }}x{{ .Height }}" >
      <img src="{{ $thumbnail.Permalink }}" itemprop="thumbnail" alt="{{ .Params.alt }}" class="galleryImage" />
    </a>
    <figcaption itemprop="caption description">
      {{ .Params.caption }}
      <span itemprop="copyrightHolder">{{ .Params.copyright }}</span>
    </figcaption>
    </figure> 

  {{ end }}
</div>

SCSS:

Due to the different device sizes, the respective photo must be reduced dynamically. You can do this in the .gallery-item class and there in the img tag with width: 100%; height: auto;

.gallery {
  width: 100%;
  display: block;
  margin: 0 auto;
}
@media only screen and (min-width: 480px) {
  .gallery {
    column-count: 1;
    column-gap: 3px;
  }
}
@media only screen and (min-width: 768px) {
  .gallery {
    column-count: 2;
    column-gap: 3px;
  }
}
@media only screen and (min-width: 992px) {
  .gallery {
    column-count: 3;
    column-gap: 0.2rem;
  }
}
.gallery-item {
  background-color: #eee;
  display: inline-block;
  margin: 0 0 0.2rem;
  width: 100%;
  border: 1px solid lightgrey;

  img {
    width: 100%;
    height: auto;
  }
}