Skip to main content
Home  › ... Razor

Images Tutorial

Tutorial HomeImages

Best practices using the Image Service

Learn about the best practices for using the image service and more. Our goals are:

  1. Make sure every image is perfectly sized as needed
  2. Multiple sizes are provided for various use cases
  3. Labels and configs made by the editor (for example, setting a priority corner) are respected by the resizer

Preparation

All the following examples use the Image Service. So to make this work, something like the following code will be at the beginning of most Razor files:


@using ToSic.Sxc.Services;
@{
  var imgSvc = GetService<IImageService>();
}

Image with URL vs. Field in img tag

As learned in the previous tutorials the img tag can be created out of URLs. The image service can also be used with Fields. The field will contain the URL as well as additional Metadata like the description or what part of the picture is important (the Crop-Anchor).

To get the most out of 2sxc and its image configuration options it's best to use the image object instead of URLs. By using the image configuration options, the settings can be easily retrieved from the corresponding image.

Picture from Content.Image

Picture from Field containing crop anchor and alt text

This description was retrieved from the image metadata.

Image to the LEFT - code and generated HTML

      @* Picture from Content.Image *@
      @imgSvc.Img(Content.Image)
    
<img src='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both' 
loading='lazy' 
class='img-fluid' 
width='1230' 
height='760' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=2460&amp;h=1520&amp;quality=75&amp;mode=crop&amp;scale=both 2460w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both 1230w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=922&amp;h=569&amp;quality=75&amp;mode=crop&amp;scale=both 922w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=615&amp;h=380&amp;quality=75&amp;mode=crop&amp;scale=both 615w' 
sizes='(max-width: 1400px) 100vw,
 1230px'>

Image to the RIGHT (note the description and anchor-parameter in the URL)

      @* Picture from Field containing crop anchor and alt text *@
      @imgSvc.Img(Content.Field("Image"))
    
<img src='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter' 
loading='lazy' 
alt='This description was retrieved from the image metadata.' 
class='img-fluid' 
width='1230' 
height='760' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=2460&amp;h=1520&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 2460w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 1230w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=922&amp;h=569&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 922w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=615&amp;h=380&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 615w' 
sizes='(max-width: 1400px) 100vw,
 1230px'>

Picture with URL vs. Field in picture tag

As learned in the previous tutorials the picture tag can be created out of URLs. The image service can also be used with Fields. The field will contain the URL as well as additional Metadata like the description or what part of the picture is important (the Crop-Anchor).

To get the most out of 2sxc and its image configuration options it's best to use the image object instead of URLs. By using the image configuration options, the settings can be easily retrieved from the corresponding image.

Picture from Content.Image

Picture from Field containing crop anchor and alt text

This description was retrieved from the image metadata.

Image to the LEFT - code and generated HTML

      @* Picture from Content.Image *@
      @imgSvc.Picture(Content.Image)
    
<picture>
<source type='image/webp' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=2460&amp;h=1520&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp 2460w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp 1230w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=922&amp;h=569&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp 922w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=615&amp;h=380&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp 615w' 
sizes='(max-width: 1400px) 100vw,
 1230px'>
<source type='image/jpeg' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=2460&amp;h=1520&amp;quality=75&amp;mode=crop&amp;scale=both 2460w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both 1230w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=922&amp;h=569&amp;quality=75&amp;mode=crop&amp;scale=both 922w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=615&amp;h=380&amp;quality=75&amp;mode=crop&amp;scale=both 615w' 
sizes='(max-width: 1400px) 100vw,
 1230px'>
<img src='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both' 
loading='lazy' 
class='img-fluid' 
width='1230' 
height='760'>
</picture>

Image to the RIGHT (note the description and anchor-parameter in the URL)

      @* Picture from Field containing crop anchor and alt text *@
      @imgSvc.Picture(Content.Field("Image"))
    
<picture>
<source type='image/webp' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=2460&amp;h=1520&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 2460w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 1230w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=922&amp;h=569&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 922w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=615&amp;h=380&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 615w' 
sizes='(max-width: 1400px) 100vw,
 1230px'>
<source type='image/jpeg' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=2460&amp;h=1520&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 2460w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 1230w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=922&amp;h=569&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 922w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=615&amp;h=380&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 615w' 
sizes='(max-width: 1400px) 100vw,
 1230px'>
<img src='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter' 
loading='lazy' 
alt='This description was retrieved from the image metadata.' 
class='img-fluid' 
width='1230' 
height='760'>
</picture>

Apply factor to the picture tag

The Image Service offers multiple parameters for further customization of the images, such as the factor. The factor works as a resize multiplier for the image as for example (0.5).

Below you will find an example:

Picture using the factor 0.5

This description was retrieved from the image metadata.

Picture using the factor 5

This description was retrieved from the image metadata.

Image to the LEFT - code and generated HTML

      @* Picture using the factor 0.5 *@
      @imgSvc.Picture(Content.Field("Image"), factor: 0.5)
    
<picture>
<source type='image/webp' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1200&amp;h=741&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 1200w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=600&amp;h=370&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 600w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=450&amp;h=278&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 450w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=300&amp;h=185&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 300w' 
sizes='(max-width: 1400px) 50vw,
 (max-width: 576px) 100vw,
 600px'>
<source type='image/jpeg' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1200&amp;h=741&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 1200w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=600&amp;h=370&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 600w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=450&amp;h=278&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 450w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=300&amp;h=185&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 300w' 
sizes='(max-width: 1400px) 50vw,
 (max-width: 576px) 100vw,
 600px'>
<img src='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=600&amp;h=370&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter' 
loading='lazy' 
alt='This description was retrieved from the image metadata.' 
class='img-fluid' 
width='600' 
height='370'>
</picture>

Image to the RIGHT (note higher resolution)

      @* Picture using the factor 5 *@
      @imgSvc.Picture(Content.Field("Image"), factor: 5)
    
<picture>
<source type='image/webp' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=3200&amp;h=1977&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 3200w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=3200&amp;h=1977&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 3200w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=3200&amp;h=1977&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 3200w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=3200&amp;h=1977&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 3200w'>
<source type='image/jpeg' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=3200&amp;h=1977&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 3200w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=3200&amp;h=1977&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 3200w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=3200&amp;h=1977&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 3200w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=3200&amp;h=1977&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 3200w'>
<img src='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=3200&amp;h=1977&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter' 
loading='lazy' 
alt='This description was retrieved from the image metadata.' 
class='img-fluid' 
width='3200' 
height='1977'>
</picture>

Create multiple image variants

The picture tag contains multiple configurations of images, which are called recipes in our ecosystem. The browser then chooses the optimal configuration based on the given srcset. Using the .Recipe("") method from the image service, you can easily add more size variants of your images.

Below you will find an example:

Picture default recipe

This description was retrieved from the image metadata.

Picture with variants for 2x and 3x of the image size

This description was retrieved from the image metadata.

Image to the LEFT - code and generated HTML

      @* Picture using the default *@
      @imgSvc.Picture(Content.Field("Image"))
    
<picture>
<source type='image/webp' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=2460&amp;h=1520&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 2460w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 1230w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=922&amp;h=569&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 922w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=615&amp;h=380&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 615w' 
sizes='(max-width: 1400px) 100vw,
 1230px'>
<source type='image/jpeg' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=2460&amp;h=1520&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 2460w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 1230w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=922&amp;h=569&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 922w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=615&amp;h=380&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 615w' 
sizes='(max-width: 1400px) 100vw,
 1230px'>
<img src='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter' 
loading='lazy' 
alt='This description was retrieved from the image metadata.' 
class='img-fluid' 
width='1230' 
height='760'>
</picture>

Image to the RIGHT (note different variants)

      @{
        var customRecipe = imgSvc.Recipe("2*, 3*");
      }
      @* Picture using recipe with 2x and 3x variants *@
      @imgSvc.Picture(Content.Field("Image"), recipe: customRecipe)
    
<picture>
<source type='image/webp' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=2800&amp;h=1730&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 2800w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=3200&amp;h=1977&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 3200w'>
<source type='image/jpeg' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=2800&amp;h=1730&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 2800w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=3200&amp;h=1977&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 3200w'>
<img src='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1400&amp;h=865&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter' 
alt='This description was retrieved from the image metadata.'>
</picture>

Choose the optimal alt text

By passing the image object, the picture tag will apply the alt text automatically.
Because alt texts are not always defined in the settings, different texts can be set as fallback.2sxc Preferably in that case, the image alt text has priority over other texts. We can create a fallback by using the Text.First(text1, text2) Method from Razor Blade.

Below you will find an example:

Image with optimal alt text (This description was retrieved from the image metadata.)

This description was retrieved from the image metadata.

@{
  var fallbackAltText = "Fallback";

  var imageFieldWithAltText = Content.Field("Image"); 
  var optimalAltText = Text.First(imageFieldWithAltText.Metadata.Description, fallbackAltText);
}
<div>
  <p><strong>Image with optimal alt text (@optimalAltText)</strong></p>
  <div style="width: 25%;">
    @imgSvc.Picture(imageFieldWithAltText, imgAlt: optimalAltText)
  </div>
</div>
This generates:
<picture>
<source type='image/webp' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=2460&amp;h=1520&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 2460w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 1230w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=922&amp;h=569&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 922w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=615&amp;h=380&amp;quality=75&amp;mode=crop&amp;scale=both&amp;format=webp&amp;anchor=bottomcenter 615w' 
sizes='(max-width: 1400px) 100vw,
 1230px'>
<source type='image/jpeg' 
srcset='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=2460&amp;h=1520&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 2460w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 1230w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=922&amp;h=569&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 922w,
/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=615&amp;h=380&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter 615w' 
sizes='(max-width: 1400px) 100vw,
 1230px'>
<img src='/Portals/tutorials/adam/Tutorial-Razor/1eSr_DjJnk-67Zdd4-fw2Q/Image/photo-1651590814269-ccf8dee671ae.jpg?w=1230&amp;h=760&amp;quality=75&amp;mode=crop&amp;scale=both&amp;anchor=bottomcenter' 
loading='lazy' 
alt='This description was retrieved from the image metadata.' 
class='img-fluid' 
width='1230' 
height='760'>
</picture>

Source Code of this file

Below you'll see the source code of the file. Note that we're just showing the main part, and hiding some parts of the file which are not relevant for understanding the essentials. Click to expand the code

@inherits Custom.Hybrid.Razor12
@using ToSic.Sxc.Services;
@using ToSic.Razor.Blade;
<!-- unimportant stuff, hidden -->

Best practices using the Image Service... <!-- unimportant stuff, hidden -->

<h2>Preparation</h2>
<p>
  All the following examples use the <a href="https://docs.2sxc.org/api/dot-net/ToSic.Sxc.Services.IImageService.html" target="_blank">Image Service</a>.
  So to make this work, something like the following code will be at the beginning of most Razor files:
</p>


@using ToSic.Sxc.Services;
@{
  var imgSvc = GetService<IImageService>();
}



<h2>Image with URL vs. Field in <code>img</code> tag</h2>
<p>
  As learned in the previous tutorials the <code>img</code> tag can be created out of URLs.
  The image service can also be used with Fields. The field will contain the URL as well as additional Metadata like the description or what part of the picture is important (the Crop-Anchor).
</p>
<p>
  To get the most out of 2sxc and its image configuration options 
  it's best to use the image object instead of URLs. By using the image configuration options,
  the settings can be easily retrieved from the corresponding image.
</p>

<!-- unimportant stuff, hidden -->
<div class="row">
  <div class="col-md">

    <p><strong>Picture from <code>Content.Image</code></strong></p>
    
      @* Picture from Content.Image *@
      @imgSvc.Img(Content.Image)
    

  </div>
  <div class="col-md">

    <p><strong>Picture from <code>Field</code> containing crop anchor and alt text</strong></p>
    
      @* Picture from Field containing crop anchor and alt text *@
      @imgSvc.Img(Content.Field("Image"))
    

  </div>
</div>





<h2>Picture with URL vs. Field in <code>picture</code> tag</h2>
<p>
  As learned in the previous tutorials the <code>picture</code> tag can be created out of URLs.
  The image service can also be used with Fields. The field will contain the URL as well as additional Metadata like the description or what part of the picture is important (the Crop-Anchor).
</p>
<p>
  To get the most out of 2sxc and its image configuration options 
  it's best to use the image object instead of URLs. By using the image configuration options,
  the settings can be easily retrieved from the corresponding image.
</p>

<div class="row">
  <div class="col-md">

    <p><strong>Picture from <code>Content.Image</code></strong></p>
    
      @* Picture from Content.Image *@
      @imgSvc.Picture(Content.Image)
    

  </div>
  <div class="col-md">

    <p><strong>Picture from <code>Field</code> containing crop anchor and alt text</strong></p>
    
      @* Picture from Field containing crop anchor and alt text *@
      @imgSvc.Picture(Content.Field("Image"))
    

  </div>
</div>



@*
  * example with other Recipe like "2x, 3x" - mit Settings
*@

<h2>Apply factor to the <code>picture</code> tag</h2>
<p>
  The Image Service offers multiple parameters for further customization of the images, such as the factor.
  The factor works as a resize multiplier for the image as for example (0.5).
  <br><br>
  Below you will find an example:
</p>

<div class="row">
  <div class="col-md">

    <p><strong>Picture using the factor <code>0.5</code></strong></p>
    
      @* Picture using the factor 0.5 *@
      @imgSvc.Picture(Content.Field("Image"), factor: 0.5)
    

  </div>
  <div class="col-md">

    <p><strong>Picture using the factor <code>5</code></strong></p>
    
      @* Picture using the factor 5 *@
      @imgSvc.Picture(Content.Field("Image"), factor: 5)
    

  </div>
</div>





<h2>Create multiple image variants</h2>
<p>
  The picture tag contains multiple configurations of images, which are called recipes in our ecosystem.
  The browser then chooses the optimal configuration based on the given srcset.

  Using the <code>.Recipe("")</code> method from the image service, you can easily add more size variants of your images.
  <br><br>
  Below you will find an example:
</p>

<div class="row">
  <div class="col-md">

    <p><strong>Picture default recipe</strong></p>
    
      @* Picture using the default *@
      @imgSvc.Picture(Content.Field("Image"))
    

  </div>
  <div class="col-md">
    <p><strong>Picture with variants for 2x and 3x of the image size</strong></p>
    
      @{
        var customRecipe = imgSvc.Recipe("2*, 3*");
      }
      @* Picture using recipe with 2x and 3x variants *@
      @imgSvc.Picture(Content.Field("Image"), recipe: customRecipe)
    

  </div>
</div>




<br>

<h2>Choose the optimal alt text</h2>
<p>
  By passing the image object, the picture tag will apply the alt text automatically.
  <br>
  Because alt texts are not always defined in the settings, different texts can be set as fallback.2sxc
  Preferably in that case, the image alt text has priority over other texts.
  We can create a fallback by using the <code>Text.First(text1, text2)</code> Method from Razor Blade. 
  <br><br>
  Below you will find an example:
</p>

<!-- unimportant stuff, hidden -->

@{
  var fallbackAltText = "Fallback";

  var imageFieldWithAltText = Content.Field("Image"); 
  var optimalAltText = Text.First(imageFieldWithAltText.Metadata.Description, fallbackAltText);
}
<div>
  <p><strong>Image with optimal alt text (@optimalAltText)</strong></p>
  <div style="width: 25%;">
    @imgSvc.Picture(imageFieldWithAltText, imgAlt: optimalAltText)
  </div>
</div>



<!-- unimportant stuff, hidden -->