Skip to content

Instantly share code, notes, and snippets.

@SelvinPL
Last active January 24, 2018 10:46
Show Gist options
  • Save SelvinPL/d94b2b617519e0510a40 to your computer and use it in GitHub Desktop.
Save SelvinPL/d94b2b617519e0510a40 to your computer and use it in GitHub Desktop.
usage: WebPUtils.isWebPSupported() works with API >= 8
package pl.selvin.android.xxxxxx;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
/**
* Created by selvin on 2015-01-28.
*/
public class WebPUtils {
//states
private static final int NOT_INITIALIZED = -1;
private static final int SUPPORTED = 1;
private static final int NOT_SUPPORTED = 0;
//why not boolean? we need more states for result caching
private static int isWebPSupportedCache = NOT_INITIALIZED;
public static boolean isWebPSupported() {
// did we already try to check?
if (isWebPSupportedCache == NOT_INITIALIZED) {
//no - trying to decode
//webp 1x1 transparent pixel with lossless
final byte[] webp1x1 = new byte[]{
0x52, 0x49, 0x46, 0x46, 0x1A, 0x00, 0x00, 0x00,
0x57, 0x45, 0x42, 0x50, 0x56, 0x50, 0x38, 0x4C,
0x0D, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,
0x10, 0x07, 0x10, 0x11, 0x11, (byte) 0x88, (byte) 0x88, (byte) 0xFE,
0x07, 0x00
};
try {
final Bitmap bitmap = BitmapFactory.decodeByteArray(webp1x1, 0, webp1x1.length);
if (bitmap != null) {
//webp supported
isWebPSupportedCache = SUPPORTED;
//don't forget to recycle!
bitmap.recycle();
} else {
//bitmap is null = not supported
isWebPSupportedCache = NOT_SUPPORTED;
}
} catch (Exception ex) {
//we got some exception = not supported
isWebPSupportedCache = NOT_SUPPORTED;
ex.printStackTrace();
}
}
return isWebPSupportedCache == SUPPORTED;
}
}
@Smileek
Copy link

Smileek commented Mar 18, 2015

First of all, thank you for the approach - having a byte array instead of an asset is a great idea.
However, I had some issues on old devices (e.g., HTC Amaze and Motorola XT910) - they returned null, even though they support webp.

So, I ended up with this array:

final byte[] webp1x1 = new byte[]{
    (byte) 0x52, (byte) 0x49, (byte) 0x46, (byte) 0x46, (byte) 0x24,
    (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x57, (byte) 0x45,
    (byte) 0x42, (byte) 0x50, (byte) 0x56, (byte) 0x50, (byte) 0x38,
    (byte) 0x20, (byte) 0x18, (byte) 0x00, (byte) 0x00, (byte) 0x00,
    (byte) 0x30, (byte) 0x01, (byte) 0x00, (byte) 0x9d, (byte) 0x01,
    (byte) 0x2a, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00,
    (byte) 0x03, (byte) 0x00, (byte) 0x34, (byte) 0x25, (byte) 0xa4,
    (byte) 0x00, (byte) 0x03, (byte) 0x70, (byte) 0x00, (byte) 0xfe,
    (byte) 0xfb, (byte) 0x94, (byte) 0x00, (byte) 0x00
};

Not quite sure, what exactly was changed - I just used another converter which, probably, provides better compliance.

Cheers.

@TWiStErRob
Copy link

@Smileek the 1x1 transparent lossless is meant to break devices. Because WebP is Android 4.0+ (Lossless, Transparency, Android 4.2.1+).
And the biggest issue is that both 4.2 and 4.2.1 is API 17, so the only safe level to start using it from is API 18.

You can detect different levels of support with yours and @SelvinPL's byte[].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment