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的主要内容,如果未能解决你的问题,请参考以下文章