c_cpp 开罗表面模糊http://stevehanov.ca/blog/index.php?id=53

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 开罗表面模糊http://stevehanov.ca/blog/index.php?id=53相关的知识,希望对你有一定的参考价值。

// to build:
// gcc -I/usr/include/cairo -lcairo -o blur blur.c

#include 
#include 
#include 
#include "cairo.h"

void cairo_image_surface_blur( cairo_surface_t* surface, double radius )
{
    // Steve Hanov, 2009
    // Released into the public domain.
    
    // get width, height
    int width = cairo_image_surface_get_width( surface );
    int height = cairo_image_surface_get_height( surface );
    unsigned char* dst = (unsigned char*)malloc(width*height*4);
    unsigned* precalc = 
        (unsigned*)malloc(width*height*sizeof(unsigned));
    unsigned char* src = cairo_image_surface_get_data( surface );
    double mul=1.f/((radius*2)*(radius*2));
    int channel;
    
    // The number of times to perform the averaging. According to wikipedia,
    // three iterations is good enough to pass for a gaussian.
    const MAX_ITERATIONS = 3; 
    int iteration;

    memcpy( dst, src, width*height*4 );

    for ( iteration = 0; iteration < MAX_ITERATIONS; iteration++ ) {
        for( channel = 0; channel < 4; channel++ ) {
            int x,y;

            // precomputation step.
            unsigned char* pix = src;
            unsigned* pre = precalc;

            pix += channel;
            for (y=0;y0) tot+=pre[-1];
                    if (y>0) tot+=pre[-width];
                    if (x>0 && y>0) tot-=pre[-width-1];
                    *pre++=tot;
                    pix += 4;
                }
            }

            // blur step.
            pix = dst + (int)radius * width * 4 + (int)radius * 4 + channel;
            for (y=radius;y= width ? width - 1 : x + radius;
                    int b = y + radius >= height ? height - 1 : y + radius;
                    int tot = precalc[r+b*width] + precalc[l+t*width] - 
                        precalc[l+b*width] - precalc[r+t*width];
                    *pix=(unsigned char)(tot*mul);
                    pix += 4;
                }
                pix += (int)radius * 2 * 4;
            }
        }
        memcpy( src, dst, width*height*4 );
    }

    free( dst );
    free( precalc );
}

int main(int argc, char* argv[])
{
    cairo_surface_t* surface;
    cairo_t* ctx;
    cairo_text_extents_t text_extents;
    cairo_font_extents_t font_extents;
    double FontSize = 100;
    double radius = 7;
    double width, height;

    if ( argc != 3 ) {
        printf("Syntax: %s  ""n", argv[0]);
        return -1;
    }

    // Get text size.
    surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, 10, 10 );
    ctx = cairo_create( surface );
    cairo_set_font_size( ctx, FontSize );

    cairo_font_extents( ctx, &font_extents );
    cairo_text_extents( ctx, argv[2], &text_extents );

    height = font_extents.ascent + font_extents.descent + radius * 2;
    width = text_extents.x_advance + radius * 2;

    cairo_destroy( ctx );
    cairo_surface_destroy( surface );

    // Draw text.
    surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height );

    ctx = cairo_create( surface );
    cairo_set_font_size( ctx, FontSize );

    cairo_move_to( ctx, 0 + radius, font_extents.ascent + radius );
    cairo_show_text( ctx, argv[2] );
    cairo_fill( ctx );

    cairo_image_surface_blur( surface, 5 );

    cairo_move_to( ctx, 0, font_extents.ascent );
    cairo_show_text( ctx, argv[2] );
    cairo_fill( ctx );

    cairo_destroy( ctx );

    cairo_surface_write_to_png( surface, argv[1] );

    cairo_surface_destroy( surface );

    return 0;
}

以上是关于c_cpp 开罗表面模糊http://stevehanov.ca/blog/index.php?id=53的主要内容,如果未能解决你的问题,请参考以下文章

表面模糊

O效率的表面模糊算法优化。

c_cpp 【32】模糊函数用法示例

c_cpp 【33】高斯模糊函数用法示例

开罗游戏,为何如此魔性?

开罗的笔画对齐