Skip to main content
Feather blending is a fast, simple blending technique that uses weighted averaging based on mask values. While it doesn’t produce results as sophisticated as multiband blending, it’s significantly faster and works well for many use cases.

Overview

Feather blending performs a direct alpha blend of images based on their masks. The transition between images is smooth but may show visible seams when blending images with significantly different colors or textures at the boundary.

Complete Example

This example is based on the test_feather() function from examples/stitch.c:66.
1
Load the images
2
Start by loading the two images to blend:
3
#include "blending.h"
#include "utils.h"

void test_feather() {
    Image img_buf1 = create_image("../files/apple.jpeg");
    Image img_buf2 = create_image("../files/orange.jpeg");
4
The setup is identical to multiband blending - load your source images using create_image().
5
Create masks for each image
6
Create gradient masks that define the blending weights:
7
    Image mask1 = create_image_mask(img_buf1.width, img_buf1.height, 0.1f, 0, 1);
    Image mask2 = create_image_mask(img_buf2.width, img_buf2.height, 0.1f, 1, 0);
8
Mask configuration:
9
  • mask1 with 0, 1: Creates a gradient from 0 (left) to 1 (right)
  • mask2 with 1, 0: Creates a gradient from 1 (left) to 0 (right)
  • 0.1f: Transition zone is 10% of image width
  • 10
    These complementary masks ensure smooth weight transitions in the overlap region.
    11
    Calculate output dimensions
    12
    Define the output canvas size:
    13
        int out = (img_buf1.width * 0.1f);
        int out_width = (img_buf1.width * 2) - (out * 2);
        StitchRect out_size = {0, 0, out_width, img_buf1.height};
    
    14
    This is identical to the multiband example - calculate overlap and determine final dimensions.
    15
    Create the feather blender
    16
    Instantiate a blender with FEATHER type:
    17
        Blender *b = create_blender(FEATHER, out_size, -1);
    
    18
    Key difference from multiband:
    19
  • Use FEATHER instead of MULTIBAND
  • Pass -1 for the number of bands (not used in feather blending)
  • Much faster initialization - no pyramid structures to build
  • 20
    Feed images to the blender
    21
    Add both images with their masks and positions:
    22
        StitchPoint pt1 = {0, 0};
        feed(b, &img_buf1, &mask1, pt1);
    
        StitchPoint pt2 = {img_buf2.width - out * 2 - 100, 0};
        feed(b, &img_buf2, &mask2, pt2);
    
    23
    The feed() function:
    24
  • First image positioned at origin (0, 0)
  • Second image positioned with calculated overlap
  • In feather mode, this accumulates weighted pixel values directly
  • No pyramid decomposition needed
  • 25
    Perform the blend
    26
    Execute the feather blending algorithm:
    27
        blend(b);
    
    28
    The feather blend() function:
    29
  • Normalizes accumulated weighted values
  • Performs direct weighted average: result = (img1 * mask1 + img2 * mask2) / (mask1 + mask2)
  • Much faster than multiband reconstruction
  • Result stored in b->result
  • 30
    Save and cleanup
    31
    Save the result and free memory:
    32
        if (b->result.data != NULL) {
            if (save_image(&b->result, "merge_feather.jpg")) {
                printf("Merged image saved\n");
            }
        }
    
        destroy_blender(b);
        destroy_image(&img_buf1);
        destroy_image(&img_buf2);
        destroy_image(&mask1);
        destroy_image(&mask2);
    }
    
    33
    Always clean up resources to prevent memory leaks.

    Expected Output

    The output file merge_feather.jpg will contain a blended image with a smooth gradient transition in the overlap region.
    Merged image saved
    

    Feather vs Multiband Comparison

    AspectFeather BlendingMultiband Blending
    SpeedVery fast (2-5x faster)Slower due to pyramid operations
    QualityGood for gradual transitionsExcellent, nearly invisible seams
    MemoryLow memory usageHigher (stores multiple pyramid levels)
    Use caseQuick previews, similar imagesProduction quality, different textures
    AlgorithmDirect weighted averageFrequency domain blending
    ParametersJust output sizeConfigurable band count

    Code Differences Summary

    // Multiband
    Blender *b = create_blender(MULTIBAND, out_size, 5);
    
    // Feather
    Blender *b = create_blender(FEATHER, out_size, -1);
    
    The only code difference is in the create_blender() call. The rest of the workflow is identical.

    When to Use Feather Blending

    • Real-time preview: When you need fast feedback during development
    • Similar images: When blending images with minimal color/brightness differences
    • Low-power devices: When computational resources are limited
    • Large images: When processing very high-resolution images where speed matters
    • Batch processing: When processing hundreds of images and speed is critical

    Performance Characteristics

    • Typical processing time for 1920×1080 images: 0.05-0.10 seconds
    • Memory usage: O(output_size) - just the output buffer
    • Parallelization: Benefits from multi-core processors
    • Linear complexity: Processing time scales linearly with image size

    Build docs developers (and LLMs) love