Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to identify whether webp image is static or animated?

I am working on a project where a user can upload webp images. I know how to convert webp images into jpg/png, but am stuck on how to identify whether the webp image is static (non-animated) or animated.

I want to identify them because I use different commands for conversion:

Command for non-animated webp to jpg:

dwebp nonanimated.webp -o jpg.jpg

Command for animated webp to non-animated webp (takes 2nd frame):

webpmux -get frame 2 animated.webp -o nonanimated.webp

But I cannot find a single command that handle both cases.

I am using PHP on the server side, and HTML and Javascript for frontend.

like image 819
harish sharma Avatar asked Dec 05 '25 21:12

harish sharma


2 Answers

After a lot of investigation i found that animated webp images always conatins some string, when open in a text editor and non animated images doesn't. The strings are ANMF and ANIM. I checked these string in all webp images which i have. So this is perfect for me. Here are some solutions in PHP, Javascript and Shell Script:

In PHP:

<?php
function isWebpAnimated($src){
    $webpContents = file_get_contents($src);
    $where = strpos($webpContents, "ANMF");
    if ($where !== FALSE){
        // animated
        $isAnimated = true;
    }
    else{
        // non animated
        $isAnimated = false;
    }
    return $isAnimated;
}
?>

In Javascript:

function isWebpAnimated(src) {
    var request = new XMLHttpRequest();
    request.open('GET', src, true);
    request.addEventListener('load', function () {
        if(request.response.indexOf("ANMF") != -1){
            // animated
            alert(true);
        }
        else{
            // non animated
            alert(false);
        }
    });
    request.send();
}

But In case of large images PHP and Javascript not working well, So best Solution is to use Shell Script, If you have Ubuntu.

In Shell Script:

echo $(grep -c "ANMF" ~/animated.webp)

return 0 if non animated, else non zero value for animated.

EDIT: In Python

def isWebpAnimated(src):
    try:
        with open(src, 'rb') as f:
            data = f.read()

        # Check if the file starts with 'RIFF' and contains 'WEBPVP8' or 'WEBPVP8X'
        # if data.startswith(b'RIFF') and (b'WEBPVP8' in data or b'WEBPVP8X' in data):

        # Now will chk a byte b"ANMF" in file data
        if b"ANMF" in data:
            # The 'ANIM' indicating that the given file is Animated
            return 1
        else:
            return 0

    except Exception as err:
        exit(f"Error Occure: {err}")

like image 64
harish sharma Avatar answered Dec 08 '25 10:12

harish sharma


There are flags in Webp header, ANIMATION among others. Small function to check it:

function isWebpAnimated($fn){
  $result = false;
  $fh = fopen($fn, "rb"); 
  fseek($fh, 12);
  if(fread($fh, 4) === 'VP8X'){
    fseek($fh, 16);
    $myByte = fread($fh, 1);
    $result = ((ord($myByte) >> 1) & 1)?true:false;
  }
  fclose($fh);
  return $result;
}

ANIM and ANMF are from next chunk headers.

RIFF container specification

like image 36
Sven Liivak Avatar answered Dec 08 '25 12:12

Sven Liivak