lazarus/components/aggpas/image_fltr_graph.dpr
mattias 36a2b1ea07 added aggpas
git-svn-id: trunk@21942 -
2009-10-01 12:24:32 +00:00

516 lines
12 KiB
ObjectPascal

//
// AggPas 2.4 RM3 Demo application
// Note: Press F1 key on run to see more info about this demo
//
// Paths: src;src\ctrl;src\svg;src\util;src\platform\win;expat-wrap
//
program
image_fltr_graph ;
uses
Math ,
agg_basics ,
agg_platform_support ,
agg_color ,
agg_pixfmt ,
agg_pixfmt_rgb ,
agg_ctrl ,
agg_slider_ctrl ,
agg_rbox_ctrl ,
agg_cbox_ctrl ,
agg_rendering_buffer ,
agg_renderer_base ,
agg_renderer_scanline ,
agg_rasterizer_scanline_aa ,
agg_scanline ,
agg_scanline_u ,
agg_scanline_p ,
agg_render_scanlines ,
agg_ellipse ,
agg_trans_affine ,
agg_conv_transform ,
agg_conv_stroke ,
agg_span_allocator ,
agg_span_interpolator_linear ,
agg_span_image_filter ,
agg_span_image_filter_rgb ,
agg_image_filters ,
agg_path_storage ;
{$I agg_mode.inc }
const
flip_y = true;
type
filter_adaptor_ptr = ^filter_adaptor;
filter_adaptor = object
m_filter : image_filter_base_ptr;
constructor Construct(filter : image_filter_base_ptr );
destructor Destruct;
function radius : double;
function calc_weight(x : double ) : double;
procedure set_radius(r : double );
end;
the_application = object(platform_support )
m_radius : slider_ctrl;
m_bilinear ,
m_bicubic ,
m_spline16 ,
m_spline36 ,
m_hanning ,
m_hamming ,
m_hermite ,
m_kaiser ,
m_quadric ,
m_catrom ,
m_gaussian ,
m_bessel ,
m_mitchell ,
m_sinc ,
m_lanczos ,
m_blackman : cbox_ctrl;
m_filters : array[0..31 ] of cbox_ctrl_ptr;
m_filter_bilinear ,
m_filter_bicubic ,
m_filter_spline16 ,
m_filter_spline36 ,
m_filter_hanning ,
m_filter_hamming ,
m_filter_hermite ,
m_filter_kaiser ,
m_filter_quadric ,
m_filter_catrom ,
m_filter_gaussian ,
m_filter_bessel ,
m_filter_mitchell ,
m_filter_sinc ,
m_filter_lanczos ,
m_filter_blackman : filter_adaptor;
m_filter_func : array[0..31 ] of filter_adaptor_ptr;
m_num_filters : unsigned;
constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
destructor Destruct;
procedure on_draw; virtual;
procedure on_key(x ,y : int; key ,flags : unsigned ); virtual;
end;
{ CONSTRUCT }
constructor filter_adaptor.Construct;
begin
m_filter:=filter;
end;
{ DESTRUCT }
destructor filter_adaptor.Destruct;
begin
if m_filter <> NIL then
dispose(m_filter );
end;
{ RADIUS }
function filter_adaptor.radius;
begin
if m_filter <> NIL then
result:=m_filter.radius
else
result:=0;
end;
{ CALC_WEIGHT }
function filter_adaptor.calc_weight;
begin
if m_filter <> NIL then
result:=m_filter.calc_weight(Abs(x ) )
else
result:=0;
end;
{ SET_RADIUS }
procedure filter_adaptor.set_radius;
begin
if m_filter <> NIL then
m_filter.set_radius(r );
end;
{ CONSTRUCT }
constructor the_application.Construct;
var
i : unsigned;
begin
inherited Construct(format_ ,flip_y_ );
m_radius.Construct (5.0 ,5.0 ,780 - 5 ,10.0 ,not flip_y_ );
m_bilinear.Construct(8.0 ,30.0 + 15 * 0 ,'bilinear' ,not flip_y_ );
m_bicubic.Construct (8.0 ,30.0 + 15 * 1 ,'bicubic ' ,not flip_y_ );
m_spline16.Construct(8.0 ,30.0 + 15 * 2 ,'spline16' ,not flip_y_ );
m_spline36.Construct(8.0 ,30.0 + 15 * 3 ,'spline36' ,not flip_y_ );
m_hanning.Construct (8.0 ,30.0 + 15 * 4 ,'hanning ' ,not flip_y_ );
m_hamming.Construct (8.0 ,30.0 + 15 * 5 ,'hamming ' ,not flip_y_ );
m_hermite.Construct (8.0 ,30.0 + 15 * 6 ,'hermite ' ,not flip_y_ );
m_kaiser.Construct (8.0 ,30.0 + 15 * 7 ,'kaiser ' ,not flip_y_ );
m_quadric.Construct (8.0 ,30.0 + 15 * 8 ,'quadric ' ,not flip_y_ );
m_catrom.Construct (8.0 ,30.0 + 15 * 9 ,'catrom ' ,not flip_y_ );
m_gaussian.Construct(8.0 ,30.0 + 15 * 10 ,'gaussian' ,not flip_y_ );
m_bessel.Construct (8.0 ,30.0 + 15 * 11 ,'bessel ' ,not flip_y_ );
m_mitchell.Construct(8.0 ,30.0 + 15 * 12 ,'mitchell' ,not flip_y_ );
m_sinc.Construct (8.0 ,30.0 + 15 * 13 ,'sinc ' ,not flip_y_ );
m_lanczos.Construct (8.0 ,30.0 + 15 * 14 ,'lanczos ' ,not flip_y_ );
m_blackman.Construct(8.0 ,30.0 + 15 * 15 ,'blackman' ,not flip_y_ );
m_filter_bilinear.Construct(new(image_filter_bilinear_ptr ,Construct ) );
m_filter_bicubic.Construct (new(image_filter_bicubic_ptr ,Construct ) );
m_filter_spline16.Construct(new(image_filter_spline16_ptr ,Construct ) );
m_filter_spline36.Construct(new(image_filter_spline36_ptr ,Construct ) );
m_filter_hanning.Construct (new(image_filter_hanning_ptr ,Construct ) );
m_filter_hamming.Construct (new(image_filter_hamming_ptr ,Construct ) );
m_filter_hermite.Construct (new(image_filter_hermite_ptr ,Construct ) );
m_filter_kaiser.Construct (new(image_filter_kaiser_ptr ,Construct ) );
m_filter_quadric.Construct (new(image_filter_quadric_ptr ,Construct ) );
m_filter_catrom.Construct (new(image_filter_catrom_ptr ,Construct ) );
m_filter_gaussian.Construct(new(image_filter_gaussian_ptr ,Construct ) );
m_filter_bessel.Construct (new(image_filter_bessel_ptr ,Construct ) );
m_filter_mitchell.Construct(new(image_filter_mitchell_ptr ,Construct ) );
m_filter_sinc.Construct (new(image_filter_sinc_ptr ,Construct(2.0 ) ) );
m_filter_lanczos.Construct (new(image_filter_lanczos_ptr ,Construct(2.0 ) ) );
m_filter_blackman.Construct(new(image_filter_blackman_ptr ,Construct(2.0 ) ) );
m_num_filters:=0;
m_filters[m_num_filters ]:=@m_bilinear; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_bicubic; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_spline16; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_spline36; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_hanning; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_hamming; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_hermite; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_kaiser; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_quadric; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_catrom; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_gaussian; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_bessel; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_mitchell; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_sinc; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_lanczos; inc(m_num_filters );
m_filters[m_num_filters ]:=@m_blackman; inc(m_num_filters );
i:=0;
m_filter_func[i ]:=@m_filter_bilinear; inc(i );
m_filter_func[i ]:=@m_filter_bicubic; inc(i );
m_filter_func[i ]:=@m_filter_spline16; inc(i );
m_filter_func[i ]:=@m_filter_spline36; inc(i );
m_filter_func[i ]:=@m_filter_hanning; inc(i );
m_filter_func[i ]:=@m_filter_hamming; inc(i );
m_filter_func[i ]:=@m_filter_hermite; inc(i );
m_filter_func[i ]:=@m_filter_kaiser; inc(i );
m_filter_func[i ]:=@m_filter_quadric; inc(i );
m_filter_func[i ]:=@m_filter_catrom; inc(i );
m_filter_func[i ]:=@m_filter_gaussian; inc(i );
m_filter_func[i ]:=@m_filter_bessel; inc(i );
m_filter_func[i ]:=@m_filter_mitchell; inc(i );
m_filter_func[i ]:=@m_filter_sinc; inc(i );
m_filter_func[i ]:=@m_filter_lanczos; inc(i );
m_filter_func[i ]:=@m_filter_blackman; inc(i );
for i:=0 to m_num_filters - 1 do
add_ctrl(m_filters[i ] );
m_radius.range_(2.0 ,8.0 );
m_radius.value_(4.0 );
m_radius.label_('Radius=%.3f' );
add_ctrl(@m_radius );
end;
{ DESTRUCT }
destructor the_application.Destruct;
begin
inherited Destruct;
m_radius.Destruct;
m_bilinear.Destruct;
m_bicubic.Destruct;
m_spline16.Destruct;
m_spline36.Destruct;
m_hanning.Destruct;
m_hamming.Destruct;
m_hermite.Destruct;
m_kaiser.Destruct;
m_quadric.Destruct;
m_catrom.Destruct;
m_gaussian.Destruct;
m_bessel.Destruct;
m_mitchell.Destruct;
m_sinc.Destruct;
m_lanczos.Destruct;
m_blackman.Destruct;
m_filter_bilinear.Destruct;
m_filter_bicubic.Destruct;
m_filter_spline16.Destruct;
m_filter_spline36.Destruct;
m_filter_hanning.Destruct;
m_filter_hamming.Destruct;
m_filter_hermite.Destruct;
m_filter_kaiser.Destruct;
m_filter_quadric.Destruct;
m_filter_catrom.Destruct;
m_filter_gaussian.Destruct;
m_filter_bessel.Destruct;
m_filter_mitchell.Destruct;
m_filter_sinc.Destruct;
m_filter_lanczos.Destruct;
m_filter_blackman.Destruct;
end;
{ ON_DRAW }
procedure the_application.on_draw;
var
pixf : pixel_formats;
rgba : aggclr;
rb : renderer_base;
rs : renderer_scanline_aa_solid;
sl : scanline_p8;
ras : rasterizer_scanline_aa;
normalized : image_filter_lut;
weights : int16_ptr;
x_start ,x_end ,y_start ,y_end ,x_center ,x ,y ,ys ,radius ,dy ,xs ,dx ,sum ,xf : double;
xfract ,ir : int;
i ,j ,n ,xint ,nn : unsigned;
p : path_storage;
pl : conv_stroke;
tr : conv_transform;
begin
// Initialize structures
pixfmt_bgr24(pixf ,rbuf_window );
rb.Construct(@pixf );
rs.Construct(@rb );
rgba.ConstrDbl(1.0 ,1.0 ,1.0 );
rb.clear (@rgba );
ras.Construct;
sl.Construct;
// Render
x_start :=125.0;
x_end :=_initial_width - 15.0;
y_start :=10.0;
y_end :=_initial_height - 10.0;
x_center:=(x_start + x_end ) / 2;
p.Construct;
pl.Construct(@p );
tr.Construct(@pl ,_trans_affine_resizing );
for i:=0 to 15 do
begin
x:=x_start + (x_end - x_start ) * i / 16.0;
p.remove_all;
p.move_to(x + 0.5 ,y_start );
p.line_to(x + 0.5 ,y_end );
ras.add_path(@tr );
if i = 8 then
rgba.ConstrInt(0 ,0 ,0 ,255 )
else
rgba.ConstrInt(0 ,0 ,0 ,100 );
rs.color_ (@rgba );
render_scanlines(@ras ,@sl ,@rs );
end;
ys:=y_start + (y_end - y_start ) / 6.0;
p.remove_all;
p.move_to (x_start ,ys );
p.line_to (x_end ,ys );
ras.add_path (@tr );
rgba.ConstrInt (0 ,0 ,0 );
rs.color_ (@rgba );
render_scanlines(@ras ,@sl ,@rs );
pl.width_(1.0 );
for i:=0 to m_num_filters - 1 do
if m_filters[i ]._status then
begin
m_filter_func[i ].set_radius(m_radius._value );
radius:=m_filter_func[i ].radius;
n :=trunc(radius * 256 * 2 );
dy:=y_end - ys;
xs:=(x_end + x_start ) / 2.0 - (radius * (x_end - x_start ) / 16.0 );
dx:=(x_end - x_start ) * radius / 8.0;
p.remove_all;
p.move_to(xs + 0.5 ,ys + dy * m_filter_func[i ].calc_weight(-radius ) );
j:=1;
while j < n do
begin
p.line_to(
xs + dx * j / n + 0.5 ,
ys + dy * m_filter_func[i ].calc_weight(j / 256.0 - radius ) );
inc(j );
end;
ras.add_path (@tr );
rgba.ConstrInt (100 ,0 ,0 );
rs.color_ (@rgba );
render_scanlines(@ras ,@sl ,@rs );
p.remove_all;
ir:=trunc(Ceil(radius ) + 0.1 );
for xint:=0 to 255 do
begin
sum:=0;
xfract:=-ir;
while xfract < ir do
begin
xf:=xint / 256.0 + xfract;
if (xf >= -radius ) or
(xf <= radius ) then
sum:=sum + m_filter_func[i ].calc_weight(xf );
inc(xfract );
end;
x:=x_center + ((-128.0 + xint ) / 128.0 ) * radius * (x_end - x_start ) / 16.0;
y:=ys + sum * 256 - 256;
if xint = 0 then
p.move_to(x ,y )
else
p.line_to(x ,y );
end;
ras.add_path (@tr );
rgba.ConstrInt (0 ,100 ,0 );
rs.color_ (@rgba );
render_scanlines(@ras ,@sl ,@rs );
normalized.Construct(m_filter_func[i ].m_filter );
weights:=normalized.weight_array;
xs:=(x_end + x_start ) / 2.0 - (normalized.diameter * (x_end - x_start ) / 32.0 );
nn:=normalized.diameter * 256;
p.remove_all;
p.move_to(xs + 0.5 ,ys + dy * int16_ptr(weights )^ / image_filter_size );
j:=1;
while j < nn do
begin
p.line_to(
xs + dx * j / n + 0.5 ,
ys + dy * int16_ptr(ptrcomp(weights ) + j * sizeof(int16 ) )^ / image_filter_size );
inc(j );
end;
ras.add_path (@tr );
rgba.ConstrInt (0 ,0 ,100 ,255 );
rs.color_ (@rgba );
render_scanlines(@ras ,@sl ,@rs );
// Free
normalized.Destruct;
end;
// Render the controls
for i:=0 to m_num_filters - 1 do
render_ctrl(@ras ,@sl ,@rs ,m_filters[i ] );
if m_sinc._status or
m_lanczos._status or
m_blackman._status then
render_ctrl(@ras ,@sl ,@rs ,@m_radius );
// Free AGG resources
ras.Destruct;
sl.Destruct;
p.Destruct;
pl.Destruct;
end;
{ ON_KEY }
procedure the_application.on_key;
begin
if key = key_f1 then
message_(
'Demonstration of the shapes of different interpolation filters. '#13 +
'Just in case if you are curious.' +
#13#13'Note: F2 key saves current "screenshot" file in this demo''s directory. ' );
end;
VAR
app : the_application;
BEGIN
app.Construct(pix_format_bgr24 ,flip_y );
app.caption_ ('Image filters'' shape comparison (F1-Help)' );
if app.init(780 ,300 ,window_resize ) then
app.run;
app.Destruct;
END.