<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/how-to-handle-webp-images-as-sprites-in-unity-fjghhcus1" -->

---
title: How to handle WebP images as sprites in Unity | daily.dev
description: Unity&#x27;s built-in image loaders (UnityWebRequestTexture and Texture2D.LoadImage) silently fail on WebP images, returning a broken placeholder texture instead of...
canonical: https://daily.dev/posts/how-to-handle-webp-images-as-sprites-in-unity-fjghhcus1
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: How to handle WebP images as sprites in Unity | daily.dev
og:description: Unity&#x27;s built-in image loaders (UnityWebRequestTexture and Texture2D.LoadImage) silently fail on WebP images, returning a broken placeholder texture instead of...
og:url: https://daily.dev/posts/how-to-handle-webp-images-as-sprites-in-unity-fjghhcus1
og:image: https://api.daily.dev/og/posts/FjGhhCUS1.png
og:image:alt: How to handle WebP images as sprites in Unity
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# How to handle WebP images as sprites in Unity

**[Radu G](https://daily.dev/sources/yapygxhj2kb928qr6a4cc)** · [@potterdev](https://daily.dev/potterdev) · 3 min read · 0 upvotes · 0 comments

## Summary

Unity's built-in image loaders (UnityWebRequestTexture and Texture2D.LoadImage) silently fail on WebP images, returning a broken placeholder texture instead of throwing an error. This can cause persistent blank sprites when a CDN serves WebP via content negotiation and broken files get cached to disk. The fix involves detecting the RIFF/WEBP byte signature and routing WebP images through ImageSharp (a pure C# decoder) while letting Unity handle PNG/JPEG normally. The post includes a complete ImageDecoder utility class with row-flipping to account for Unity's bottom-up texture coordinate system, and highlights the importance of checking LoadImage's return value before caching.

## Content

My game pulls cover art from a CDN, caches it, makes a sprite. Worked for months. Then random covers started showing up blank. Not always the same ones, which drove me nuts.

Finally dumped the bytes of a broken one to a file and looked at it. Starts with RIFF, then WEBP a few bytes in. The CDN was sometimes serving WebP instead of JPEG.

Unity's image loading (UnityWebRequestTexture and Texture2D.LoadImage) only reads PNG and JPEG. Hand it WebP and it doesn't throw. It just gives you a broken little placeholder texture and moves on. No error at all.

And my cache wrote the file to disk before checking if it decoded, so once a WebP landed there it stayed broken on every future load. That's why some covers were blank permanently and others were fine.

The fix was a managed WebP decoder (ImageSharp, since it's pure C# and I didn't want native libs for three build targets). Now I check the first bytes, and if it's WebP I decode it that way, otherwise Unity handles it like normal. Also stopped caching files that fail to decode.

```
/// <summary>
/// Decodes downloaded image bytes into a <see cref="Texture2D"/>.
/// Unity's built-in loaders only understand PNG and JPEG, so WebP payloads
/// (which some CDNs serve via content negotiation) are decoded with ImageSharp.
/// Returns <c>null</c> when the bytes cannot be decoded so callers can avoid
/// caching or displaying a broken texture.
/// </summary>
public static class ImageDecoder
{
    public static Texture2D DecodeToTexture(byte[] bytes)
    {
        if (bytes == null || bytes.Length < 12) return null;

        return IsWebP(bytes) ? DecodeWebP(bytes) : DecodeNative(bytes);
    }

    
// RIFF....WEBP container signature.
    
private static bool IsWebP(byte[] b) =>
        b[0] == 'R' && b[1] == 'I' && b[2] == 'F' && b[3] == 'F' &&
        b[8] == 'W' && b[9] == 'E' && b[10] == 'B' && b[11] == 'P';

    private static Texture2D DecodeNative(byte[] bytes)
    {
        var texture = new Texture2D(2, 2);
        if (texture.LoadImage(bytes)) return texture;

        Object.Destroy(texture);
        return null;
    }

    private static Texture2D DecodeWebP(byte[] bytes)
    {
        try
        {
            using var image = Image.Load<Rgba32>(bytes);
            var width = image.Width;
            var height = image.Height;
            var pixels = new Color32[width * height];

            
// ImageSharp rows run top-to-bottom; Unity textures are bottom-up, so flip.
            
for (var y = 0; y < height; y++)
            {
                var row = image.DangerousGetPixelRowMemory(y).Span;
                var destRow = (height - 1 - y) * width;
                for (var x = 0; x < width; x++)
                {
                    var p = row[x];
                    pixels[destRow + x] = new Color32(p.R, p.G, p.B, p.A);
                }
            }

            var texture = new Texture2D(width, height, TextureFormat.
RGBA32
, false);
            texture.SetPixels32(pixels);
            texture.Apply();
            return texture;
        }
        catch (System.Exception exception)
        {
            Debug.LogError($"Failed to decode WebP image: {exception.Message}");
            return null;
        }
    }
}
```

Also turns out LoadImage returns a bool telling you if it worked, which I'd been ignoring the whole time. 🤦

Anyone else hit the WebP thing? Feels like it's going to bite more people as CDNs default to it.

## Similar posts on daily.dev

- [How to Convert JPG to WebP Images \(Free & Fast\)](https://daily.dev/posts/how-to-convert-jpg-to-webp-images-free-fast--oscznlr5h) · Medium · 1 upvotes · 1 comments

---

Tags: [#webdev](https://daily.dev/tags/webdev), [#c#](https://daily.dev/tags/c#), [#unity](https://daily.dev/tags/unity)

[View this post on daily.dev](https://daily.dev/posts/how-to-handle-webp-images-as-sprites-in-unity-fjghhcus1)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"DiscussionForumPosting","mainEntityOfPage":"https://daily.dev/posts/how-to-handle-webp-images-as-sprites-in-unity-fjghhcus1","headline":"How to handle WebP images as sprites in Unity","text":"Unity's built-in image loaders (UnityWebRequestTexture and Texture2D.LoadImage) silently fail on WebP images, returning a broken placeholder texture instead of throwing an error. This can cause persistent blank sprites when a CDN serves WebP via content negotiation and broken files get cached to disk. The fix involves detecting the RIFF/WEBP byte signature and routing WebP images through ImageSharp (a pure C# decoder) while letting Unity handle PNG/JPEG normally. The post includes a complete ImageDecoder utility class with row-flipping to account for Unity's bottom-up texture coordinate system, and highlights the importance of checking LoadImage's return value before caching.","url":"https://daily.dev/posts/how-to-handle-webp-images-as-sprites-in-unity-fjghhcus1","datePublished":"2026-08-04T09:48:00.170Z","dateModified":"2026-08-04T09:48:18.711Z","author":{"@type":"Person","name":"Radu G","url":"https://daily.dev/potterdev","image":"https://avatars.githubusercontent.com/u/26082414?v=4","interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"EndorseAction"},"userInteractionCount":160}},"image":"https://media.daily.dev/image/upload/s--Kccjcjhh--/f_auto/v1785836880/posts/FjGhhCUS1?_a=BAMAMicg0","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"isPartOf":{"@type":"WebPage","url":"https://daily.dev/sources/yapygxhj2kb928qr6a4cc","name":"Radu G"}}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Radu G","item":"https://daily.dev/sources/yapygxhj2kb928qr6a4cc"},{"@type":"ListItem","position":3,"name":"How to handle WebP images as sprites in Unity"}]}
```

