libyuv: A Powerful C++ Library for Image Format Conversion and Scaling

🖼️ libyuv: A High-Performance Image Format Conversion and Scaling Library Open-Sourced by Google

Have you encountered these issues in audio and video development, camera processing, image encoding, or real-time communication (such as WebRTC)?

“How to efficiently convert NV12 to RGB?”
“How to convert between YUV and RGB?”
“How to quickly scale or rotate images?”
“Is there a cross-platform image processing library that supports SIMD optimization?”

The answer is: libyuv

GitHub Repository (Community Maintained): https://github.com/lemenkov/libyuv
Original Author: Google (Previously used in WebRTC, Chrome)
License: BSD 3-Clause (Open Source Free)
Language: C/C++

🔍 What is libyuv?

libyuv is a C++ image processing library developed and open-sourced by Google, focusing on:

Efficient conversion between YUV and RGB formats, image scaling, rotation, cropping, and color space processing.

It is widely used in:

  • WebRTC (real-time audio and video communication)
  • Video conferencing software (such as the underlying processing in Zoom, Teams)
  • Camera preview (Android, Linux V4L2)
  • Video encoders/decoders (FFmpeg plugins)
  • Image capture and display systems

✅ Core Features

Feature Description
🚀 High Performance Optimized using SIMD instructions (SSE, AVX, NEON)
🔄 Diverse Formats Supports YUV (I420, NV12, NV21, YUY2, UYVY), RGB (ARGB, BGRA, RGB24), etc.
🔍 Image Processing Scaling (bilinear, box filter), rotation, cropping, flipping
🌐 Cross-Platform Supports Windows, Linux, macOS, Android, iOS
🧩 No External Dependencies Pure C/C++ implementation, does not depend on OpenCV
🆓 BSD License Can be used for commercial projects
📦 Modular Design Conversion or scaling functions can be used independently

🛠️ Installation and Integration

Method 1: Compile from Source (Recommended)

git clone https://github.com/lemenkov/libyuv.git
cd libyuv
mkdir build && cd build

# Generate project using CMake
cmake ..
make -j$(nproc)

# Install
sudo make install

Method 2: Use vcpkg (C++ Package Manager)

vcpkg install libyuv

Method 3: Directly Integrate Source Code

Copy the include/ and src/ folders into your project, and compile cpu_id.cc, convert*.cc, scale.cc, and other source files.

💡 First Example: YUV to RGB

yuv_to_rgb.cpp

#include <libyuv.h>
#include <stdio.h>
#include <vector>

int main() {
    // Assume there is a 640x480 NV12 image
    int width = 640;
    int height = 480;

    // Allocate Y and UV buffers (NV12 format)
    size_t y_size = width * height;
    size_t uv_size = width * height / 2;
    std::vector<uint8_t> nv12(y_size + uv_size);

    // Simulate filling NV12 data (actual data read from camera or file)
    // ... Data filling omitted ...

    // Prepare output RGB24 buffer
    std::vector<uint8_t> rgb(width * height * 3);

    // Use libyuv to convert NV12 to RGB24
    int ret = libyuv::NV12ToRGB24(
        nv12.data(),                   // Y plane
        nv12.data() + y_size,          // UV plane
        width, height,
        rgb.data(),                    // Output RGB
        width * 3                      // RGB stride
    );

    if (ret != 0) {
        fprintf(stderr, "Conversion failed, error code: %d\n", ret);
        return -1;
    }

    printf("✅ Successfully converted %dx%d NV12 to RGB24\n", width, height);
    return 0;
}

✅ Compile and Run

g++ yuv_to_rgb.cpp -o yuv_to_rgb -l yuv -std=c++11
./yuv_to_rgb

🧩 Core Functionality Analysis

1. Format Conversion (Color Space Conversion)

// YUV -> RGB
I420ToARGB(y, y_stride, u, u_stride, v, v_stride, argb, argb_stride, width, height);
NV12ToRGB24(nv12_y, nv12_uv, width, height, rgb, rgb_stride);

// RGB -> YUV
ARGBToI420(argb, argb_stride, y, y_stride, u, u_stride, v, v_stride, width, height);

// Other formats
UYVYToARGB(uyvy, uyvy_stride, argb, argb_stride, width, height);

2. Image Scaling

// Scale I420 image
I420Scale(
    src_y, src_y_stride, src_u, src_u_stride, src_v, src_v_stride,
    src_width, src_height,
    dst_y, dst_y_stride, dst_u, dst_u_stride, dst_v, dst_v_stride,
    dst_width, dst_height,
    libyuv::kFilterBilinear  // Filter type
);

3. Image Rotation and Flipping

// Rotate I420 image
I420Rotate(src_y, src_y_stride, src_u, src_u_stride, src_v, src_v_stride,
           dst_y, dst_y_stride, dst_u, dst_u_stride, dst_v, dst_v_stride,
           src_width, src_height, libyuv::kRotate90);

// Mirror flip
I420Mirror(y, y_stride, u, u_stride, v, v_stride,
           width, height);

4. Cropping and Merging

// Crop a sub-region from a larger image
I420Copy(src_y + offset_y * src_stride, src_stride,
         src_u + offset_u * src_stride, src_stride,
         src_v + offset_v * src_stride, src_stride,
         dst_y, dst_y_stride, dst_u, dst_u_stride, dst_v, dst_v_stride,
         crop_width, crop_height);

🌐 Supported Image Formats

Format Description
YUV Planar I420, YV12
YUV Semi-Planar NV12, NV21
YUV Packed YUY2, UYVY, YUV2
RGB ARGB, BGRA, ABGR, RGBA, RGB24, RAW (Bayer)
Alpha Support Supports formats with transparency channels

🎯 Practical Application Scenarios

Scenario Description
WebRTC Converting NV12 from camera capture to ARGB for rendering
Video Surveillance Scaling and stitching YUV data from multiple cameras
Live Streaming Preprocessing (rotation, cropping) before encoding
Android Camera Processing ImageFormat.NV21 data
Medical Imaging YUV/RGB conversion of DICOM images
Game Screen Recording Fast scaling and format conversion

🆚 Comparison with Other Solutions

Solution Advantages Disadvantages
libyuv ✅ High performance, SIMD optimized, lightweight
OpenCV ✅ Comprehensive functionality ❌ Large size, many dependencies, slow startup
FFmpeg libswscale ✅ Powerful, supports multiple formats ❌ Complex configuration, low-level C interface
Manual Implementation ✅ Complete control ❌ Prone to errors, difficult to optimize

libyuv is the preferred choice for lightweight, high-performance image conversion.

✅ Why Choose libyuv?

  • Originated from Google WebRTC: Proven in large-scale production
  • SIMD Optimization: Acceleration with SSE, AVX (Intel), NEON (ARM)
  • Pure C/C++: Easy to integrate, no Python/Java dependencies
  • BSD License: Freely usable for commercial projects
  • Active Community: Although Google is no longer actively maintaining it, the community version continues to be updated

📚 Learning Resources

✅ Summary

libyuv is a “cornerstone tool” in audio and video development.

It focuses on doing one thing well:

Efficiently and reliably completing image format conversion and geometric transformations.

Whether you are developing:

  • Real-time audio and video applications
  • Camera capture systems
  • Video editing software
  • Embedded vision devices

libyuv can provide you with exceptional performance and stability.

“Make image processing lightning fast.”

Integrate libyuv into your project now and unleash the full potential of YUV processing!⚡📷

Leave a Comment