image-optimization

Guidance for implementing responsive images, format optimization, and image processing pipelines for headless CMS.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "image-optimization" with this command: npx skills add melodic-software/claude-code-plugins/melodic-software-claude-code-plugins-image-optimization

Image Optimization

Guidance for implementing responsive images, format optimization, and image processing pipelines for headless CMS.

When to Use This Skill

  • Implementing responsive image delivery

  • Converting images to modern formats (WebP, AVIF)

  • Building image processing pipelines

  • Implementing focal point cropping

  • Optimizing image loading performance

Responsive Image Patterns

Srcset for Resolution Switching

<!-- Basic srcset with width descriptors --> <img src="/images/hero.jpg" srcset=" /images/hero-400w.jpg 400w, /images/hero-800w.jpg 800w, /images/hero-1200w.jpg 1200w, /images/hero-1600w.jpg 1600w " sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 800px" alt="Hero image"

<!-- Srcset with pixel density --> <img src="/images/logo.png" srcset=" /images/logo.png 1x, /images/logo@2x.png 2x, /images/logo@3x.png 3x " alt="Logo"

Picture Element for Art Direction

<picture> <!-- Mobile: Square crop --> <source media="(max-width: 600px)" srcset="/images/hero-mobile.webp" type="image/webp"

<source media="(max-width: 600px)" srcset="/images/hero-mobile.jpg"

<!-- Desktop: Wide crop --> <source srcset="/images/hero-desktop.webp" type="image/webp"

<!-- Fallback --> <img src="/images/hero-desktop.jpg" alt="Hero"> </picture>

Image Processing Service

Core Processing

public class ImageProcessingService { public async Task<Stream> ProcessAsync( Stream source, ImageProcessingOptions options) { using var image = await Image.LoadAsync(source);

    // Resize
    if (options.Width.HasValue || options.Height.HasValue)
    {
        var resizeOptions = new ResizeOptions
        {
            Size = new Size(
                options.Width ?? 0,
                options.Height ?? 0),
            Mode = options.ResizeMode,
            Position = options.FocalPoint != null
                ? CalculateAnchor(options.FocalPoint, image.Size)
                : AnchorPositionMode.Center
        };

        image.Mutate(x => x.Resize(resizeOptions));
    }

    // Apply effects
    if (options.Blur > 0)
    {
        image.Mutate(x => x.GaussianBlur(options.Blur));
    }

    if (options.Grayscale)
    {
        image.Mutate(x => x.Grayscale());
    }

    // Encode to target format
    var outputStream = new MemoryStream();
    await EncodeAsync(image, outputStream, options);

    outputStream.Position = 0;
    return outputStream;
}

private async Task EncodeAsync(
    Image image,
    Stream output,
    ImageProcessingOptions options)
{
    switch (options.Format)
    {
        case ImageFormat.WebP:
            await image.SaveAsWebpAsync(output, new WebpEncoder
            {
                Quality = options.Quality,
                Method = WebpEncodingMethod.BestQuality
            });
            break;

        case ImageFormat.Avif:
            await image.SaveAsAvifAsync(output, new AvifEncoder
            {
                Quality = options.Quality
            });
            break;

        case ImageFormat.Jpeg:
            await image.SaveAsJpegAsync(output, new JpegEncoder
            {
                Quality = options.Quality,
                ColorType = JpegEncodingColor.YCbCrRatio420
            });
            break;

        case ImageFormat.Png:
            await image.SaveAsPngAsync(output, new PngEncoder
            {
                CompressionLevel = PngCompressionLevel.BestCompression
            });
            break;
    }
}

}

public class ImageProcessingOptions { public int? Width { get; set; } public int? Height { get; set; } public ResizeMode ResizeMode { get; set; } = ResizeMode.Max; public FocalPoint? FocalPoint { get; set; } public ImageFormat Format { get; set; } = ImageFormat.WebP; public int Quality { get; set; } = 80; public float Blur { get; set; } public bool Grayscale { get; set; } }

public class FocalPoint { public float X { get; set; } // 0-1, left to right public float Y { get; set; } // 0-1, top to bottom }

public enum ImageFormat { Jpeg, Png, WebP, Avif, Gif }

Preset-Based Processing

public class ImagePresets { public static readonly Dictionary<string, ImageProcessingOptions> Presets = new() { ["thumbnail"] = new() { Width = 150, Height = 150, ResizeMode = ResizeMode.Crop, Format = ImageFormat.WebP, Quality = 75 }, ["card"] = new() { Width = 400, Height = 300, ResizeMode = ResizeMode.Crop, Format = ImageFormat.WebP, Quality = 80 }, ["hero"] = new() { Width = 1920, Height = 800, ResizeMode = ResizeMode.Crop, Format = ImageFormat.WebP, Quality = 85 }, ["og-image"] = new() { Width = 1200, Height = 630, ResizeMode = ResizeMode.Crop, Format = ImageFormat.Jpeg, Quality = 90 }, ["blur-placeholder"] = new() { Width = 20, Height = 20, Format = ImageFormat.Jpeg, Quality = 30, Blur = 5 } }; }

Focal Point Cropping

Focal Point Model

public class FocalPointService { public AnchorPositionMode CalculateAnchor( FocalPoint focal, Size imageSize, Size targetSize) { // Calculate which part of image will be cropped var imageAspect = (float)imageSize.Width / imageSize.Height; var targetAspect = (float)targetSize.Width / targetSize.Height;

    if (Math.Abs(imageAspect - targetAspect) &#x3C; 0.01f)
    {
        return AnchorPositionMode.Center;
    }

    // Determine crop direction
    var cropHorizontal = imageAspect > targetAspect;

    if (cropHorizontal)
    {
        // Cropping sides, use X focal point
        return focal.X switch
        {
            &#x3C; 0.33f => AnchorPositionMode.Left,
            > 0.66f => AnchorPositionMode.Right,
            _ => AnchorPositionMode.Center
        };
    }
    else
    {
        // Cropping top/bottom, use Y focal point
        return focal.Y switch
        {
            &#x3C; 0.33f => AnchorPositionMode.Top,
            > 0.66f => AnchorPositionMode.Bottom,
            _ => AnchorPositionMode.Center
        };
    }
}

}

Storing Focal Point

public class MediaItem { public Guid Id { get; set; } public string FileName { get; set; } = string.Empty;

// Focal point for smart cropping
public FocalPoint? FocalPoint { get; set; }

}

// Set via API PATCH /api/media/{id} { "focalPoint": { "x": 0.3, "y": 0.2 } }

On-the-Fly Image Transformation

URL-Based Transformation

Base URL

https://cdn.example.com/media/hero.jpg

With transformations

https://cdn.example.com/media/hero.jpg?w=800&#x26;h=600&#x26;fit=crop https://cdn.example.com/media/hero.jpg?w=400&#x26;format=webp&#x26;q=80 https://cdn.example.com/media/hero.jpg?preset=thumbnail

Transformation Endpoint

[Route("media/{path}")] public class ImageTransformController : ControllerBase { [HttpGet] [ResponseCache(Duration = 31536000, VaryByQueryKeys = new[] { "" })] public async Task<IActionResult> GetTransformed( string path, [FromQuery] int? w, [FromQuery] int? h, [FromQuery] string? format, [FromQuery] int? q, [FromQuery] string? fit, [FromQuery] string? preset) { // Get original image var original = await _mediaService.GetStreamAsync(path); if (original == null) return NotFound();

    // Build options from query or preset
    var options = preset != null
        ? ImagePresets.Presets.GetValueOrDefault(preset) ?? new()
        : new ImageProcessingOptions
        {
            Width = w,
            Height = h,
            Format = ParseFormat(format),
            Quality = q ?? 80,
            ResizeMode = ParseFit(fit)
        };

    // Process image
    var processed = await _imageProcessor.ProcessAsync(original, options);

    return File(processed, GetMimeType(options.Format));
}

}

Srcset Generation

Responsive Image Service

public class ResponsiveImageService { private readonly int[] _defaultWidths = { 320, 640, 960, 1280, 1920 };

public ResponsiveImageData GenerateSrcset(
    MediaItem media,
    ResponsiveImageOptions? options = null)
{
    options ??= new ResponsiveImageOptions();
    var widths = options.Widths ?? _defaultWidths;

    var srcset = widths
        .Where(w => w &#x3C;= (media.Metadata.Width ?? int.MaxValue))
        .Select(w => new SrcsetEntry
        {
            Url = BuildTransformUrl(media, w, options.Format),
            Width = w
        })
        .ToList();

    return new ResponsiveImageData
    {
        Src = BuildTransformUrl(media, options.DefaultWidth, options.Format),
        Srcset = srcset,
        Sizes = options.Sizes ?? "(max-width: 1200px) 100vw, 1200px",
        Alt = media.Metadata.Alt ?? "",
        Width = media.Metadata.Width,
        Height = media.Metadata.Height,
        BlurDataUrl = options.IncludeBlurPlaceholder
            ? BuildTransformUrl(media, 20, ImageFormat.Jpeg, blur: 5)
            : null
    };
}

private string BuildTransformUrl(
    MediaItem media,
    int width,
    ImageFormat format,
    int? blur = null)
{
    var query = $"?w={width}&#x26;format={format.ToString().ToLower()}";
    if (blur.HasValue) query += $"&#x26;blur={blur}";
    return $"{_cdnBaseUrl}/media/{media.StoragePath}{query}";
}

}

public class ResponsiveImageData { public string Src { get; set; } = string.Empty; public List<SrcsetEntry> Srcset { get; set; } = new(); public string Sizes { get; set; } = string.Empty; public string Alt { get; set; } = string.Empty; public int? Width { get; set; } public int? Height { get; set; } public string? BlurDataUrl { get; set; } }

public class SrcsetEntry { public string Url { get; set; } = string.Empty; public int Width { get; set; }

public override string ToString() => $"{Url} {Width}w";

}

Low-Quality Image Placeholders (LQIP)

Blur Hash Generation

public class BlurHashService { public string GenerateBlurHash(Image image, int componentsX = 4, int componentsY = 3) { // Resize to small dimensions for hash calculation using var small = image.Clone(x => x.Resize(32, 32));

    // Calculate blur hash
    var pixels = new Pixel[32, 32];
    for (var y = 0; y &#x3C; 32; y++)
    {
        for (var x = 0; x &#x3C; 32; x++)
        {
            var pixel = small[x, y];
            pixels[x, y] = new Pixel(pixel.R, pixel.G, pixel.B);
        }
    }

    return BlurHash.Encode(pixels, componentsX, componentsY);
}

}

Placeholder Strategies

Strategy Size Quality Use Case

Blur hash ~30 chars Good Inline in HTML

Tiny JPEG ~500 bytes Medium Data URL

Dominant color 7 chars Simple CSS background

SVG trace ~2KB Good Artistic sites

Performance Best Practices

Lazy Loading

<!-- Native lazy loading --> <img src="/images/photo.jpg" loading="lazy" decoding="async" alt="Photo"

<!-- With blur placeholder --> <div class="image-container" style="background: url(data:image/jpeg;base64,...)"> <img src="/images/photo.jpg" loading="lazy" onload="this.parentElement.style.background = 'none'" alt="Photo"

</div>

Format Selection

public ImageFormat SelectOptimalFormat(string acceptHeader, ImageFormat preferred) { if (acceptHeader.Contains("image/avif")) return ImageFormat.Avif;

if (acceptHeader.Contains("image/webp"))
    return ImageFormat.WebP;

return preferred;

}

Image API Response

{ "data": { "id": "media-123", "original": { "url": "https://cdn.example.com/media/original/hero.jpg", "width": 3840, "height": 2160, "mimeType": "image/jpeg", "sizeBytes": 2456789 }, "responsive": { "src": "https://cdn.example.com/media/hero.jpg?w=1280&#x26;format=webp", "srcset": "https://cdn.example.com/media/hero.jpg?w=320&#x26;format=webp 320w, ...", "sizes": "(max-width: 1200px) 100vw, 1200px" }, "placeholder": { "blurHash": "LEHV6nWB2yk8pyo0adR*.7kCMdnj", "dataUrl": "data:image/jpeg;base64,/9j/4AAQ..." }, "focalPoint": { "x": 0.5, "y": 0.3 } } }

Related Skills

  • media-asset-management

  • Media library and upload

  • cdn-media-delivery

  • CDN integration and caching

  • headless-api-design

  • Image API endpoints

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

design-thinking

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

plantuml-syntax

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

system-prompt-engineering

No summary provided by upstream source.

Repository SourceNeeds Review