Answers.Body: <h1>1.</h1>
  
  <p>If you need a rotated version of an image but Imager can't transform the image programmatically, you could just create <strong>2 different asset fields</strong> for the same image. One field for the landscape orientation, and the other for portrait. </p>
  
  <p>In that table view example you showed above I'd imagine you would need 2 columns: <strong>Image Landscape</strong> and <strong>Image Portrait</strong>.</p>
  
  <p>You could access those images in your template with something like this:</p>
  
  <pre><code>{% for row in entry.textImages.all() %}
  
    {% set imagePortrait = row.textImagePortrait.one() ?? null %}
    {% set imageLandscape = row.textImageLandscape.one() ?? null %}
  
    {% if imagePortrait %}
      ...
    {% endif %}
  
    {% if imageLandscape %}
      ...
    {% endif %}
  
  {% endfor %}
  </code></pre>
  
  <hr>
  
  <h1>2.</h1>
  
  <p>If you want to swap out a different images (size, cropping, orientation, etc) you need "<a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images#Art_direction" rel="nofollow noreferrer">art direction</a>."</p>
  
  <p><code>sizes</code> and <code>srcset</code> attribtues work together to help the browser choose the right resolution image. But ultimately it's up to the browser which image to use.</p>
  
  <p>The <code>picture</code> and <code>source</code> tags <em>explicitly</em> tell the browser what to do based on the <code>media</code> attribute. <em>"Browser do this..."</em></p>
  
  <p>Here's the most basic example of serving a different image for portrait orientation (landscape is the default):</p>
  
  <pre><code>&lt;picture&gt;
    &lt;source media="(orientation: portrait)" srcset="portrait.jpg"&gt;
    &lt;img src="landscape.jpg" alt=""&gt;
  &lt;/picture&gt;
  </code></pre>
  
  <p>Codepen example: <a href="https://codepen.io/alexroper/pen/ExYpvVR?editors=1000" rel="nofollow noreferrer">Art direction image with orientation, simple</a></p>
  
  <p>Then you can add on different sizes a resolutions to each source by expanding on <code>srcset</code> and <code>sizes</code>.</p>
  
  <pre><code>&lt;picture&gt;
      &lt;source media="(orientation: portrait)"
              srcset="portrait.jpg 400w,
                      portrait-md.jpg 600w,
                      portrait-lg.jpg 800w" 
              sizes="(min-width: 400px) 400px,
                     100vw"&gt;
      &lt;img src="landscape.jpg"
           srcset="landscape.jpg 600w,
                   landscape-md.jpg 800w,
                   landscape-lg.jpg 1200w"
           sizes="(min-width: 600px) 600px,
                  100vw"
           alt=""&gt;
  &lt;/picture&gt;
  </code></pre>
  
  <p>Codepen example: <a href="https://codepen.io/alexroper/pen/vYBaZMP?editors=1000" rel="nofollow noreferrer">Art direction image with orientation, complex</a></p>
  
  <p>In that example, both images start out 100% of the viewport width on small screens. But the portrait image doesn't get larger than 400px wide, and the landscape image doesn't get larger than 600px.</p>
  
  <hr>
  
  <h1>3.</h1>
  
  <p>Since you have to transform 2 images with similar options, there's a few ways you can optimize this.</p>
  
  <p>You can store your array of options to reuse:</p>
  
  <pre><code>{% set imageOptions = {
    format: imageType,
    allowUpscale: false,
    resizeFilter: 'lanczos',
    effects: { unsharpMask: [0, 0.55, 0.55, 0.008] },
    interlace: false,
    convertToRGB: true,
    filenamePattern: fileName ~ '_{fullname|hash}.{extension}'
  } %}
  </code></pre>
  
  <p>You can use the <a href="https://github.com/aelvan/Imager-Craft#filltransforms-bool" rel="nofollow noreferrer"><code>fillTransforms</code></a> option in Imager to fill in sizes between your min an max size.</p>
  
  <pre><code>{# Taken from Imager docs #}
  {% set transformedImages = craft.imager.transformImage(image, [
      { width: 1200 }, 
      { width: 400 }
      ], { ratio: 16/9, position: image.getFocalPoint() }, 
      { fillTransforms: true }) %}
  </code></pre>
  
  <p>Here's what this might look like when you output the image:</p>
  
  <pre><code>{% set transformedPortraitImages = craft.imager.transformImage(imagePortrait, [
      { height: 2000 },
      { height: 400 }
    ], imageOptions, { fillTransforms: true }) %}
  
  {% set transformedLandscapeImages = craft.imager.transformImage(imageLandscape, [
      { width: 2000 },
      { width: 400 }
    ], imageOptions, { fillTransforms: true }) %}
  
  
  &lt;picture&gt;
      {% if imagePortrait %}
        &lt;source media="(orientation: portrait)"
                srcset="{{ craft.imager.srcset(transformedPortraitImages) }}"
                sizes="..."&gt;
      {% endif %}  
      &lt;img src="{{ transformedLandscapeImages[(transformedLandscapeImages|length - 1)].url }}"
           srcset="{{ craft.imager.srcset(transformedLandscapeImages) }}"
           sizes="..."
           alt=""&gt;
  &lt;/picture&gt;
  </code></pre>
  
  <p>This code may not meet your needs completely, but hopefully this is enough to set you on the right path.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-09-15T12:04:40.770Z
Answers.Text: The problem is more how to handle it in Craft than the HTML. I also thought about the second column. Problem is then a can not set extra style/css on that image. Also i'm not sure how to get the image from the second column (code). Something like this would be nice: https://i.imgur.com/i0ahCeM.jpg
Answers.UserDisplayName: MrGlasspoole
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-09-15T12:41:54.870Z
Answers.Text: Okay, I added an example of accessing 2 images in a row in the template.
Answers.UserDisplayName: Alex Roper
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-09-15T12:53:29.807Z
Answers.Text: What does the "?? null" do? First time i see it. That way it means i have to put the Imager code twice in my template. Also I'm not sure if the width and height settings also work on the portrait images.
Answers.UserDisplayName: MrGlasspoole
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-09-15T20:59:12.877Z
Answers.Text: `??` is the null-coalescing operator. https://twig.symfony.com/doc/2.x/templates.html#other-operators. It prevents errors when calling a method like .one() if there isn't asset selected. Here's an excellent explanation of how and why to use it: https://straightupcraft.com/events/twigs-null-coalescing-operator
Answers.UserDisplayName: Alex Roper
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-09-15T21:14:41.177Z
Answers.Text: Yes, you would transform both portrait and landscape images. I can add some suggestions for simplifying that.
Answers.UserDisplayName: Alex Roper
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-09-15T23:18:41.200Z
Answers.Text: I updated my question how i did it now. A view weeks ago i was playing with "fillTransforms" but it did not work how i wanted it. Can't remember why i did it how i do it now. Problem left for now is the last paragraph of my question.
Answers.UserDisplayName: MrGlasspoole
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-09-15T23:40:30.203Z
Answers.Text: To show the portrait image below 800px as well try `media="(orientation: portrait), (max-width: 799px)"`. That gets evaluated like an "or" statement. It matches if either in portrait orientation or the viewport is less than 800px.
Answers.UserDisplayName: Alex Roper
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-09-16T02:22:48.690Z
Answers.Text: That way the rotated picture is to width if the phone is landscape because the other images are only 60vw in landscape and below 799px. If i omit "media" and do sizes="(orientation: portrait) 80vw, (max-width: 799px) 60vw" i have the rotated image also on my PC (though the desktop is more than 799?).
Answers.UserDisplayName: MrGlasspoole
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-09-16T03:49:55.577Z
Answers.Text: Seems like i have to set both. media="(orientation: portrait), (max-width: 799px)" and sizes="(orientation: portrait) 80vw, (max-width: 799px) 60vw". If i omit "media" i get the rotated image on the desktop.
Answers.UserDisplayName: MrGlasspoole
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-09-15T11:39:18.867Z
Answers.LastActivityDate: 2019-09-16T03:55:51.450Z
Answers.LastEditDate: 2019-09-16T03:55:51.450Z
Answers.UserDisplayName: Alex Roper
Body: <p>I have the feeling I'm the only one with such complicated code for my images.<br>
  With so many devices with different view ports and landscape / portrait...  </p>
  
  <p>How do you all handle your picture tag art-direction responsive stuff?</p>
  
  <p>Now i want some images to be rotated if the device is in portrait mode.<br>
  Imager has no transform for rotate. So i need to upload the rotated image and set it as alternative to the other image.</p>
  
  <p><strong>Edit:</strong><br>
  The code i have now after changing it:  </p>
  
  <pre><code>{% if entry.textImages | length %}
  
    {% for row in entry.textImages.all() %}
  
      {% set image = row.textImage.one() %}
      {% set imageWidth = row.textImageWidth %}
      {% set imageHeight = row.textImageHeight %}
      {% set imageClass = row.textImageClass %}
  
      {% set imagePortrait = row.textImagePortrait.one() %}
  
      {% set imageType = row.textImageType.value %}
      {% set fileName = image.filename|trim('.' ~ image.extension, 'right') %}
  
      {% set tempImage = craft.imager.transformImage(image, { width: 2000 },
        {
          allowUpscale: false,
          resizeFilter: 'lanczos',
          effects: { unsharpMask: [0, 0.55, 0.55, 0.008] },
          interlace: false,
          convertToRGB: true
        }
      ) %}
  
      {% if imageHeight is not empty %}
        {% set tempHeight = tempImage.getHeight() %}
        {% set imageSizes = [{ height: tempHeight },
                             { height: imageHeight * 4.5 },
                             { height: imageHeight * 4.25 },
                             { height: imageHeight * 4 },
                             { height: imageHeight * 3.75 },
                             { height: imageHeight * 3.5 },
                             { height: imageHeight * 3.25 },
                             { height: imageHeight * 3 },
                             { height: imageHeight * 2.75 },
                             { height: imageHeight * 2.5 },
                             { height: imageHeight * 2.25 },
                             { height: imageHeight * 2 },
                             { height: imageHeight * 1.75 },
                             { height: imageHeight * 1.5 },
                             { height: imageHeight * 1.25 },
                             { height: imageHeight }] %}
      {% else %}
        {% set tempWidth = tempImage.getWidth() %}
        {% set imageSizes = [{ width: tempWidth },
                             { width: imageWidth * 4.5 },
                             { width: imageWidth * 4.25 },
                             { width: imageWidth * 4 },
                             { width: imageWidth * 3.75 },
                             { width: imageWidth * 3.5 },
                             { width: imageWidth * 3.25 },
                             { width: imageWidth * 3 },
                             { width: imageWidth * 2.75 },
                             { width: imageWidth * 2.5 },
                             { width: imageWidth * 2.25 },
                             { width: imageWidth * 2 },
                             { width: imageWidth * 1.75 },
                             { width: imageWidth * 1.5 },
                             { width: imageWidth * 1.25 },
                             { width: imageWidth }] %}
      {% endif %}
  
      {% set transformedImages = craft.imager.transformImage(tempImage, imageSizes,
        {
          format: imageType,
          allowUpscale: false,
          resizeFilter: 'lanczos',
          effects: { unsharpMask: [0, 0.55, 0.55, 0.008] },
          interlace: false,
          convertToRGB: true,
          filenamePattern: fileName ~ '_{fullname|hash}.{extension}'
        }
      ) %}
  
      {% set transformedImagesWidth = transformedImages[15].getWidth() %}
      {% set imagePortraitSizes = [{ width: transformedImagesWidth * 4.5 },
                                   { width: transformedImagesWidth * 4.25 },
                                   { width: transformedImagesWidth * 4 },
                                   { width: transformedImagesWidth * 3.75 },
                                   { width: transformedImagesWidth * 3.5 },
                                   { width: transformedImagesWidth * 3.25 },
                                   { width: transformedImagesWidth * 3 },
                                   { width: transformedImagesWidth * 2.75 },
                                   { width: transformedImagesWidth * 2.5 },
                                   { width: transformedImagesWidth * 2.25 },
                                   { width: transformedImagesWidth * 2 },
                                   { width: transformedImagesWidth * 1.75 },
                                   { width: transformedImagesWidth * 1.5 },
                                   { width: transformedImagesWidth * 1.25 },
                                   { width: transformedImagesWidth }] %}
  
      {% set transformedPortraitImages = craft.imager.transformImage(imagePortrait, imagePortraitSizes,
        {
          format: imageType,
          allowUpscale: false,
          resizeFilter: 'lanczos',
          effects: { unsharpMask: [0, 0.55, 0.55, 0.008] },
          interlace: false,
          convertToRGB: true
        }
      ) %}
  
      &lt;picture&gt;
        {% if imagePortrait is not empty %}
          &lt;source media="(orientation: portrait)"
                  sizes="80vw"
                  srcset="{{ craft.imager.srcset(transformedPortraitImages) }}"&gt;
        {% endif %}
        &lt;img class="anchor {% if imageClass is not empty %}{{ imageClass }}{% endif %}"
             src="{{ transformedImages[15].getUrl() }}"
             sizes="{% if row.textImageVW is not empty %}
                      (orientation: portrait) {{ row.textImageVW }}vw,
                      (orientation: landscape) and (max-width: 799px) {{ row.textImageVW }}vw,
                    {% else %}
                      (orientation: portrait) 80vw,
                      (orientation: landscape) and (max-width: 799px) 60vw,
                    {% endif %}
                    {% if imageHeight is not empty %}{{ transformedImagesWidth }}{% else %}{{ imageWidth }}{% endif %}px"
             srcset="{{ craft.imager.srcset(transformedImages) }}"
             title="{{ image.title }}"
             alt="{{ image.altText }}"&gt;
      &lt;/picture&gt;
  
    {% endfor %}
  
  {% endif %}
  </code></pre>
  
  <p>And this is a entry:<br>
  <a href="https://i.sstatic.net/j9WC8.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/j9WC8.jpg" alt="enter image description here"></a>  </p>
  
  <p>To calculate the width for the portrait view image i use the width of the transformed landscape image (transformedImagesWidth).
  The reason is that the images should align.  </p>
  
  <p>You can see it here:<br>
  <a href="https://skulltronics.net/phantasialand-hoerspiel-und-videokassetten" rel="nofollow noreferrer">Phantasialand Hörspiel &amp; Videokassetten</a><br>
  On a PC you see the case and two tapes in one row.<br>
  On a phone they are one below the other and the tapes rotate.  </p>
  
  <p>Only thing i don't like right now is that if i rotate the phone to landscape that i get the landscape image. But below 800px it should still show the portrait image.</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-09-13T14:00:29.043Z
Comments.Text: I think you are over-complicating things. Why not just crop the image to different proportions for different size screens? Alternatively, If you really do think you need to rotate the image, and I can't see why you would, do it with css by simply adding a class like `.rotate-90` as required.
Comments.UserDisplayName: Seth Warburton
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-09-13T14:24:44.843Z
Comments.Text: @Seth Warburton i need to rotate because it makes no sense to crop a cassette/vhs tape. I tried it with CSS but only CSS does not work without JavaScript to recalculate the viewport.
Comments.UserDisplayName: MrGlasspoole
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-09-13T14:37:30.977Z
Comments.Text: Re-calulate the viewport?? Just use add height and width attrs to your `<img`, no reflow, no .js required.
Comments.UserDisplayName: Seth Warburton
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-09-13T15:34:23.747Z
Comments.Text: @SethWarburton How do you know height and width? In sizes you set vw and in CSS you can only use %. If i rotate in CSS on "@media all and (orientation:portrait)" the picture goes over the edges of the screen. Also setting 80% there will not work because that is 80% of the image and not screen. Also that way the browser will not download the smaller image (bandwidth). Isn't the picture tag not for delivering different art-direction?
Comments.UserDisplayName: MrGlasspoole
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-09-15T23:27:30.303Z
Comments.Text: @Seth Warburton Also JS would not work: https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images#Why_cant_we_just_do_this_using_CSS_or_JavaScript
Comments.UserDisplayName: MrGlasspoole
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-09-16T07:18:18.340Z
Comments.Text: How do you know the height and width?? Ask Craft, width="{{ asset.getWidth() }}" height="{{ asset.getHeight() }}"> as detailed in the docs: https://docs.craftcms.com/v3/image-transforms.html#defining-transforms-in-your-templates
Comments.UserDisplayName: Seth Warburton
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-09-16T10:15:35.973Z
Comments.Text: @Seth Warburton height and width of the viewport/device. Did you read the Mozilla article...
Comments.UserDisplayName: MrGlasspoole
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-09-17T11:40:59.223Z
Comments.Text: Yo have completely misunderstood me @MrGlasspoole, I was trying to help but am giving up now. No need to read the article because 1) I am intimately familiar with how responsive images work and b) I already have a performant responsive image solution in Craft which is easy to use, easy to implement, and works perfectly.
Comments.UserDisplayName: Seth Warburton
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-09-17T18:20:18.660Z
Comments.Text: @Seth Warburton I appreciate your help. But i wonder how you do it if Mozilla says it can't be done with CSS because then the image is already downloaded.
Comments.UserDisplayName: MrGlasspoole
Tags: <craft3><plugin-imager>
Title: switch / rotate images based on device orientation (landscape / portrait)
ThreadText: # switch / rotate images based on device orientation (landscape / portrait)
  
  (Asked by: username_0 on 2019-09-13)
  
  I have the feeling I'm the only one with such complicated code for my images.  
  With so many devices with different view ports and landscape / portrait...
  
  How do you all handle your picture tag art-direction responsive stuff?
  
  Now i want some images to be rotated if the device is in portrait mode.  
  Imager has no transform for rotate. So i need to upload the rotated image and set it as alternative to the other image.
  
  **Edit:**  
  The code i have now after changing it:
  
  ```
  {% if entry.textImages | length %}
  
    {% for row in entry.textImages.all() %}
  
      {% set image = row.textImage.one() %}
      {% set imageWidth = row.textImageWidth %}
      {% set imageHeight = row.textImageHeight %}
      {% set imageClass = row.textImageClass %}
  
      {% set imagePortrait = row.textImagePortrait.one() %}
  
      {% set imageType = row.textImageType.value %}
      {% set fileName = image.filename|trim('.' ~ image.extension, 'right') %}
  
      {% set tempImage = craft.imager.transformImage(image, { width: 2000 },
        {
          allowUpscale: false,
          resizeFilter: 'lanczos',
          effects: { unsharpMask: [0, 0.55, 0.55, 0.008] },
          interlace: false,
          convertToRGB: true
        }
      ) %}
  
      {% if imageHeight is not empty %}
        {% set tempHeight = tempImage.getHeight() %}
        {% set imageSizes = [{ height: tempHeight },
                             { height: imageHeight * 4.5 },
                             { height: imageHeight * 4.25 },
                             { height: imageHeight * 4 },
                             { height: imageHeight * 3.75 },
                             { height: imageHeight * 3.5 },
                             { height: imageHeight * 3.25 },
                             { height: imageHeight * 3 },
                             { height: imageHeight * 2.75 },
                             { height: imageHeight * 2.5 },
                             { height: imageHeight * 2.25 },
                             { height: imageHeight * 2 },
                             { height: imageHeight * 1.75 },
                             { height: imageHeight * 1.5 },
                             { height: imageHeight * 1.25 },
                             { height: imageHeight }] %}
      {% else %}
        {% set tempWidth = tempImage.getWidth() %}
        {% set imageSizes = [{ width: tempWidth },
                             { width: imageWidth * 4.5 },
                             { width: imageWidth * 4.25 },
                             { width: imageWidth * 4 },
                             { width: imageWidth * 3.75 },
                             { width: imageWidth * 3.5 },
                             { width: imageWidth * 3.25 },
                             { width: imageWidth * 3 },
                             { width: imageWidth * 2.75 },
                             { width: imageWidth * 2.5 },
                             { width: imageWidth * 2.25 },
                             { width: imageWidth * 2 },
                             { width: imageWidth * 1.75 },
                             { width: imageWidth * 1.5 },
                             { width: imageWidth * 1.25 },
                             { width: imageWidth }] %}
      {% endif %}
  
      {% set transformedImages = craft.imager.transformImage(tempImage, imageSizes,
        {
          format: imageType,
          allowUpscale: false,
          resizeFilter: 'lanczos',
          effects: { unsharpMask: [0, 0.55, 0.55, 0.008] },
          interlace: false,
          convertToRGB: true,
          filenamePattern: fileName ~ '_{fullname|hash}.{extension}'
        }
      ) %}
  
      {% set transformedImagesWidth = transformedImages[15].getWidth() %}
      {% set imagePortraitSizes = [{ width: transformedImagesWidth * 4.5 },
                                   { width: transformedImagesWidth * 4.25 },
                                   { width: transformedImagesWidth * 4 },
                                   { width: transformedImagesWidth * 3.75 },
                                   { width: transformedImagesWidth * 3.5 },
                                   { width: transformedImagesWidth * 3.25 },
                                   { width: transformedImagesWidth * 3 },
                                   { width: transformedImagesWidth * 2.75 },
                                   { width: transformedImagesWidth * 2.5 },
                                   { width: transformedImagesWidth * 2.25 },
                                   { width: transformedImagesWidth * 2 },
                                   { width: transformedImagesWidth * 1.75 },
                                   { width: transformedImagesWidth * 1.5 },
                                   { width: transformedImagesWidth * 1.25 },
                                   { width: transformedImagesWidth }] %}
  
      {% set transformedPortraitImages = craft.imager.transformImage(imagePortrait, imagePortraitSizes,
        {
          format: imageType,
          allowUpscale: false,
          resizeFilter: 'lanczos',
          effects: { unsharpMask: [0, 0.55, 0.55, 0.008] },
          interlace: false,
          convertToRGB: true
        }
      ) %}
  
      <picture>
        {% if imagePortrait is not empty %}
          <source media="(orientation: portrait)"
                  sizes="80vw"
                  srcset="{{ craft.imager.srcset(transformedPortraitImages) }}">
        {% endif %}
        <img class="anchor {% if imageClass is not empty %}{{ imageClass }}{% endif %}"
             src="{{ transformedImages[15].getUrl() }}"
             sizes="{% if row.textImageVW is not empty %}
                      (orientation: portrait) {{ row.textImageVW }}vw,
                      (orientation: landscape) and (max-width: 799px) {{ row.textImageVW }}vw,
                    {% else %}
                      (orientation: portrait) 80vw,
                      (orientation: landscape) and (max-width: 799px) 60vw,
                    {% endif %}
                    {% if imageHeight is not empty %}{{ transformedImagesWidth }}{% else %}{{ imageWidth }}{% endif %}px"
             srcset="{{ craft.imager.srcset(transformedImages) }}"
             title="{{ image.title }}"
             alt="{{ image.altText }}">
      </picture>
  
    {% endfor %}
  
  {% endif %}
  
  ```
  
  And this is a entry:  
  [![enter image description here](https://i.sstatic.net/j9WC8.jpg)](https://i.sstatic.net/j9WC8.jpg)
  
  To calculate the width for the portrait view image i use the width of the transformed landscape image (transformedImagesWidth).
  The reason is that the images should align.
  
  You can see it here:  
  [Phantasialand Hörspiel & Videokassetten](https://skulltronics.net/phantasialand-hoerspiel-und-videokassetten)  
  On a PC you see the case and two tapes in one row.  
  On a phone they are one below the other and the tapes rotate.
  
  Only thing i don't like right now is that if i rotate the phone to landscape that i get the landscape image. But below 800px it should still show the portrait image.
  
  **Tags:** craft3, plugin-imager
  
  > **Comments:**
  > **username_1**: I think you are over-complicating things. Why not just crop the image to different proportions for different size screens? Alternatively, If you really do think you need to rotate the image, and I can't see why you would, do it with css by simply adding a class like `.rotate-90` as required.  
  > **username_0**: @username_1 i need to rotate because it makes no sense to crop a cassette/vhs tape. I tried it with CSS but only CSS does not work without JavaScript to recalculate the viewport.  
  > **username_1**: Re-calulate the viewport?? Just use add height and width attrs to your `<img`, no reflow, no .js required.  
  > **username_0**: @username_1 How do you know height and width? In sizes you set vw and in CSS you can only use %. If i rotate in CSS on "@media all and (orientation:portrait)" the picture goes over the edges of the screen. Also setting 80% there will not work because that is 80% of the image and not screen. Also that way the browser will not download the smaller image (bandwidth). Isn't the picture tag not for delivering different art-direction?  
  > **username_0**: @username_1 Also JS would not work: https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images#Why_cant_we_just_do_this_using_CSS_or_JavaScript  
  > **username_1**: How do you know the height and width?? Ask Craft, width="{{ asset.getWidth() }}" height="{{ asset.getHeight() }}"> as detailed in the docs: https://docs.craftcms.com/v3/image-transforms.html#defining-transforms-in-your-templates  
  > **username_0**: @username_1 height and width of the viewport/device. Did you read the Mozilla article...  
  > **username_1**: Yo have completely misunderstood me @username_0, I was trying to help but am giving up now. No need to read the article because 1) I am intimately familiar with how responsive images work and b) I already have a performant responsive image solution in Craft which is easy to use, easy to implement, and works perfectly.  
  > **username_0**: @username_1 I appreciate your help. But i wonder how you do it if Mozilla says it can't be done with CSS because then the image is already downloaded.  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_2 on 2019-09-15. Score: 2
  
  # 1.
  
  If you need a rotated version of an image but Imager can't transform the image programmatically, you could just create **2 different asset fields** for the same image. One field for the landscape orientation, and the other for portrait.
  
  In that table view example you showed above I'd imagine you would need 2 columns: **Image Landscape** and **Image Portrait**.
  
  You could access those images in your template with something like this:
  
  ```
  {% for row in entry.textImages.all() %}
  
    {% set imagePortrait = row.textImagePortrait.one() ?? null %}
    {% set imageLandscape = row.textImageLandscape.one() ?? null %}
  
    {% if imagePortrait %}
      ...
    {% endif %}
  
    {% if imageLandscape %}
      ...
    {% endif %}
  
  {% endfor %}
  
  ```
  
  ---
  
  # 2.
  
  If you want to swap out a different images (size, cropping, orientation, etc) you need "[art direction](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images#Art_direction)."
  
  `sizes` and `srcset` attribtues work together to help the browser choose the right resolution image. But ultimately it's up to the browser which image to use.
  
  The `picture` and `source` tags *explicitly* tell the browser what to do based on the `media` attribute. *"Browser do this..."*
  
  Here's the most basic example of serving a different image for portrait orientation (landscape is the default):
  
  ```
  <picture>
    <source media="(orientation: portrait)" srcset="portrait.jpg">
    <img src="landscape.jpg" alt="">
  </picture>
  
  ```
  
  Codepen example: [Art direction image with orientation, simple](https://codepen.io/username_2/pen/ExYpvVR?editors=1000)
  
  Then you can add on different sizes a resolutions to each source by expanding on `srcset` and `sizes`.
  
  ```
  <picture>
      <source media="(orientation: portrait)"
              srcset="portrait.jpg 400w,
                      portrait-md.jpg 600w,
                      portrait-lg.jpg 800w" 
              sizes="(min-width: 400px) 400px,
                     100vw">
      <img src="landscape.jpg"
           srcset="landscape.jpg 600w,
                   landscape-md.jpg 800w,
                   landscape-lg.jpg 1200w"
           sizes="(min-width: 600px) 600px,
                  100vw"
           alt="">
  </picture>
  
  ```
  
  Codepen example: [Art direction image with orientation, complex](https://codepen.io/username_2/pen/vYBaZMP?editors=1000)
  
  In that example, both images start out 100% of the viewport width on small screens. But the portrait image doesn't get larger than 400px wide, and the landscape image doesn't get larger than 600px.
  
  ---
  
  # 3.
  
  Since you have to transform 2 images with similar options, there's a few ways you can optimize this.
  
  You can store your array of options to reuse:
  
  ```
  {% set imageOptions = {
    format: imageType,
    allowUpscale: false,
    resizeFilter: 'lanczos',
    effects: { unsharpMask: [0, 0.55, 0.55, 0.008] },
    interlace: false,
    convertToRGB: true,
    filenamePattern: fileName ~ '_{fullname|hash}.{extension}'
  } %}
  
  ```
  
  You can use the [`fillTransforms`](https://github.com/aelvan/Imager-Craft#filltransforms-bool) option in Imager to fill in sizes between your min an max size.
  
  ```
  {# Taken from Imager docs #}
  {% set transformedImages = craft.imager.transformImage(image, [
      { width: 1200 }, 
      { width: 400 }
      ], { ratio: 16/9, position: image.getFocalPoint() }, 
      { fillTransforms: true }) %}
  
  ```
  
  Here's what this might look like when you output the image:
  
  ```
  {% set transformedPortraitImages = craft.imager.transformImage(imagePortrait, [
      { height: 2000 },
      { height: 400 }
    ], imageOptions, { fillTransforms: true }) %}
  
  {% set transformedLandscapeImages = craft.imager.transformImage(imageLandscape, [
      { width: 2000 },
      { width: 400 }
    ], imageOptions, { fillTransforms: true }) %}
  
  <picture>
      {% if imagePortrait %}
        <source media="(orientation: portrait)"
                srcset="{{ craft.imager.srcset(transformedPortraitImages) }}"
                sizes="...">
      {% endif %}  
      <img src="{{ transformedLandscapeImages[(transformedLandscapeImages|length - 1)].url }}"
           srcset="{{ craft.imager.srcset(transformedLandscapeImages) }}"
           sizes="..."
           alt="">
  </picture>
  
  ```
  
  This code may not meet your needs completely, but hopefully this is enough to set you on the right path.
  
  > **Comments:**
  > **username_0**: The problem is more how to handle it in Craft than the HTML. I also thought about the second column. Problem is then a can not set extra style/css on that image. Also i'm not sure how to get the image from the second column (code). Something like this would be nice: https://i.imgur.com/i0ahCeM.jpg  
  > **username_2**: Okay, I added an example of accessing 2 images in a row in the template.  
  > **username_0**: What does the "?? null" do? First time i see it. That way it means i have to put the Imager code twice in my template. Also I'm not sure if the width and height settings also work on the portrait images.  
  > **username_2**: `??` is the null-coalescing operator. https://twig.symfony.com/doc/2.x/templates.html#other-operators. It prevents errors when calling a method like .one() if there isn't asset selected. Here's an excellent explanation of how and why to use it: https://straightupcraft.com/events/twigs-null-coalescing-operator  
  > **username_2**: Yes, you would transform both portrait and landscape images. I can add some suggestions for simplifying that.  
  > **username_0**: I updated my question how i did it now. A view weeks ago i was playing with "fillTransforms" but it did not work how i wanted it. Can't remember why i did it how i do it now. Problem left for now is the last paragraph of my question.  
  > **username_2**: To show the portrait image below 800px as well try `media="(orientation: portrait), (max-width: 799px)"`. That gets evaluated like an "or" statement. It matches if either in portrait orientation or the viewport is less than 800px.  
  > **username_0**: That way the rotated picture is to width if the phone is landscape because the other images are only 60vw in landscape and below 799px. If i omit "media" and do sizes="(orientation: portrait) 80vw, (max-width: 799px) 60vw" i have the rotated image also on my PC (though the desktop is more than 799?).  
  > **username_0**: Seems like i have to set both. media="(orientation: portrait), (max-width: 799px)" and sizes="(orientation: portrait) 80vw, (max-width: 799px) 60vw". If i omit "media" i get the rotated image on the desktop.  
  
  ---
  
  