Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPG vs WebP performance on Android

I´m trying to get performance stats about how Android load, decode and render WebP images against JPG, but my results are a little confuse.

Decoding WebP images to Bitmap are slow than JPG.

Some stats:

  • WebP 66% less file size than JPG, 267% more time to decode.
  • WebP 38% less file size than JPG, 258% more time to decode.
  • WebP 89% less file size than JPG, 319% more time to decode.

Has someone know about any issue on performance, or why WebP decoding is harder than JPG.

This is my test:

public class BulkLoadFromDisk implements Runnable {

    private static final String TAG = "BulkLoadFromDisk";

    private static final int TIMES = 10;

    private final ResourceProvider resourceProvider;
    private final Activity context;
    private final int counter;
    private long averageLoadTimeNano;
    private long averageConvertTimeNano;
    private final ImagesFactory.FORMAT format;
    private final CompleteListener listener;

    public BulkLoadFromDisk(Activity context, ResourceProvider resourceProvider,
                            CompleteListener listener, ImagesFactory.FORMAT format) {
        this.resourceProvider = resourceProvider;
        this.context = context;
        this.counter = resourceProvider.length();
        this.format = format;
        this.listener = listener;
    }

    @Override
    public void run() {

        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            Log.e(TAG, e.getMessage(), e);
        }

        try {
            String file;
            long loadBegin, loadEnd;
            long convertBegin, convertEnd;
            Bitmap bitmap; Drawable d;
            String extension = "." + format.name().toLowerCase();
            InputStream inputStream;
            for(int j = 0; j < TIMES; j++) {

                for(int index = 0; index < counter; index++) {
                    file = resourceProvider.get(index).concat(extension);
                    inputStream = context.getAssets().open(file);

                    // Load bitmap from file
                    loadBegin = System.nanoTime();
                    bitmap = BitmapFactory.decodeStream(inputStream);
                    assert (bitmap != null);
                    loadEnd = System.nanoTime();

                    // Convert bitmap to drawable
                    convertBegin = System.nanoTime();
                    d = new BitmapDrawable(context.getResources(), bitmap);
                    assert (d != null);
                    convertEnd = System.nanoTime();

                    averageLoadTimeNano += (loadEnd - loadBegin);
                    averageConvertTimeNano += (convertEnd - convertBegin);
                }

            }
            averageLoadTimeNano = averageLoadTimeNano / (TIMES * counter);
            averageConvertTimeNano = averageConvertTimeNano / (TIMES * counter);

            if(listener != null && context != null) {
                context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        listener.onComplete(BulkLoadFromDisk.this);
                    }
                });
            }

        }
        catch (final IOException e) {

            if(listener != null && context!= null) {

                context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        listener.onError(e);
                    }
                });

            }

        } finally {
            System.gc();
        }

    }

    public interface CompleteListener {
        void onComplete(BulkLoadFromDisk task);
        void onError(Exception e);
    }

    public long getAverageLoadTimeNano() {
        return averageLoadTimeNano;
    }

    public long getAverageConvertTimeNano() {
        return averageConvertTimeNano;
    }

    public ImagesFactory.FORMAT getFormat() {
        return format;
    }

    public String resultToString() {
        final StringBuffer sb = new StringBuffer("BulkLoadFromDisk{");
        sb.append("averageLoadTimeNano=").append(Utils.nanosToBest(averageLoadTimeNano).first
                + Utils.nanosToBest(averageLoadTimeNano).second);
        sb.append(", averageConvertTimeNano=").append(Utils.nanosToBest(averageConvertTimeNano).first
                + Utils.nanosToBest(averageConvertTimeNano).second);
        sb.append(", format=").append(format);
        sb.append('}');
        return sb.toString();
    }
like image 449
Roman Avatar asked Jun 14 '16 13:06

Roman


People also ask

Is WebP faster than JPG?

Conclusion. The study evaluated WebP compression in comparison to JPEG. We observed that the average WebP file size is 25%-34% smaller compared to JPEG file size at equivalent SSIM index. The SSIM vs bpp plots showed that WebP consistently required less bits per pixel than JPEG for the same SSIM index.

Should I use WebP or JPG?

Using WebP, webmasters and web developers can create smaller, richer images that make the web faster. WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller than comparable JPEG images at equivalent SSIM quality index.

Is WebP supported by Android?

Lossy WebP images are supported in Android 4.0 (API level 14) and higher, and lossless and transparent WebP images are supported in Android 4.3 (API level 18) and higher. This page shows how to convert images to WebP format and how to convert WebP images to PNG format.

Is WebP lighter than JPG?

WebP offers file sizes that are around 30% smaller than JPEG without a quality gap. It also provides transparency (alpha channel) like PNG, and the ability to animate images like the GIF format. Chances are, you've seen WebP images before.


1 Answers

I know this is an old question and i haven't studied the in-depths of WebP yet, but it's probably because it's a more complex algorith, hence why it has better compression ratios than JPEG. WebP is based on the VP8 codec, which is itself an royalty-free competitor to the widely-used, and heavy, h264 format.

JPEG is widely used, however, it's a really old format and is considerably simpler than the VP8 codec of WebP.

like image 172
Allan Araújo Avatar answered Sep 20 '22 21:09

Allan Araújo