im_draw_smudge() done
This commit is contained in:
parent
25fbe71c74
commit
f4e970fb72
@ -4,7 +4,8 @@
|
||||
- colourspace has a source_space option
|
||||
- operations can be tagged as "deprecated"
|
||||
- redo im_draw_circle(), im_draw_flood(), im_draw_line(), im_draw_mask(),
|
||||
im_draw_image(), im_draw_rect(), im_draw_point(), im_read_point() as classes
|
||||
im_draw_image(), im_draw_rect(), im_draw_point(), im_read_point(),
|
||||
im_draw_smudge() as classes
|
||||
- better rounding in vips_flatten()
|
||||
- VipsStatistic operations are sequential
|
||||
|
||||
|
76
TODO
76
TODO
@ -1,3 +1,50 @@
|
||||
- need to do im_label_regions in morph
|
||||
|
||||
- swap VipsArea ink for VipsArrayDouble?
|
||||
|
||||
- ink to vec etc. should work for complex .. output or accept a double-length
|
||||
vector
|
||||
|
||||
needs to work for eg. vips_linear() as well
|
||||
|
||||
if vector.len is == bands, expand to complex by setting imaginary == 0
|
||||
if vector.len == bands * 2, set imaginary from constant
|
||||
if vector.len == 1, bandup with imaginary == 0
|
||||
if vector.len == 2, bandup setting imaginary from vector
|
||||
|
||||
what about bands == 2? ambigious
|
||||
|
||||
we must insist vector.length == 2 or bands * 2 for complex, or have the
|
||||
current behaviour of imaginary == 0 always
|
||||
|
||||
- try:
|
||||
|
||||
$ vips draw_smudge
|
||||
usage:
|
||||
draw_smudge image ink left top width height
|
||||
blur a rectangle on an image
|
||||
where:
|
||||
image - Image to draw on, input VipsImage
|
||||
ink - Colour for pixels, input VipsArrayDouble
|
||||
left - Rect to fill, input gint
|
||||
top - Rect to fill, input gint
|
||||
width - Rect to fill, input gint
|
||||
height - Rect to fill, input gint
|
||||
|
||||
nice if we could hide the "ink" param
|
||||
|
||||
also for
|
||||
|
||||
draw_image
|
||||
draw_line_user
|
||||
|
||||
we could either move ink to the other operations or make a new subclass of
|
||||
draw containing the ink arg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- try
|
||||
|
||||
$ vips getpoint
|
||||
@ -38,11 +85,6 @@
|
||||
|
||||
|
||||
|
||||
- swap VipsArea ink for VipsArrayDouble?
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- try:
|
||||
|
||||
@ -52,29 +94,7 @@
|
||||
|
||||
with wtc.jpg, segv if libvips is compiled with -O, OK without
|
||||
|
||||
- ink to vec etc. should work for complex .. output or accept a double-length
|
||||
vector
|
||||
|
||||
needs to work for eg. vips_linear() as well
|
||||
|
||||
if vector.len is == bands, expand to complex by setting imaginary == 0
|
||||
if vector.len == bands * 2, set imaginary from constant
|
||||
if vector.len == 1, bandup with imaginary == 0
|
||||
if vector.len == 2, bandup setting imaginary from vector
|
||||
|
||||
what about bands == 2? ambigious
|
||||
|
||||
we must insist vector.length == 2 or bands * 2 for complex, or have the
|
||||
current behaviour of imaginary == 0 always
|
||||
|
||||
- inplace
|
||||
|
||||
can we set a region for the pixels we will modify?
|
||||
|
||||
is there any point doing this? only useful on 32-bit machines, which
|
||||
don't really exist any more
|
||||
|
||||
- need to do mosaicing and inplace, plus im_label_regions in morph
|
||||
- need to do mosaicing
|
||||
|
||||
- now vips_linear() has uchar output, can we do something with orc?
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
noinst_LTLIBRARIES = libdeprecated.la
|
||||
|
||||
libdeprecated_la_SOURCES = \
|
||||
inplace_dispatch.c \
|
||||
tone.c \
|
||||
freq_dispatch.c \
|
||||
im_linreg.c \
|
||||
|
@ -4603,6 +4603,12 @@ im_draw_point( VipsImage *image, int x, int y, VipsPel *ink )
|
||||
return( vips_draw_point( image, vec, n, x, y, NULL ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_draw_smudge( VipsImage *im, int left, int top, int width, int height )
|
||||
{
|
||||
return( vips_draw_smudge( im, left, top, width, height, NULL ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_read_point( VipsImage *image, int x, int y, VipsPel *ink )
|
||||
{
|
||||
|
@ -12,9 +12,6 @@ libdraw_la_SOURCES = \
|
||||
draw_line.c \
|
||||
draw_line_mask.c \
|
||||
draw_line_user.c \
|
||||
im_draw_smudge.c \
|
||||
inplace_dispatch.c \
|
||||
old_draw.c \
|
||||
old_draw.h
|
||||
draw_smudge.c
|
||||
|
||||
AM_CPPFLAGS = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@
|
||||
|
@ -138,6 +138,7 @@ vips_draw_operation_init( void )
|
||||
extern GType vips_draw_line_user_get_type( void );
|
||||
extern GType vips_draw_circle_get_type( void );
|
||||
extern GType vips_draw_flood_get_type( void );
|
||||
extern GType vips_draw_smudge_get_type( void );
|
||||
|
||||
vips_draw_rect_get_type();
|
||||
vips_draw_image_get_type();
|
||||
@ -147,6 +148,7 @@ vips_draw_operation_init( void )
|
||||
vips_draw_line_user_get_type();
|
||||
vips_draw_circle_get_type();
|
||||
vips_draw_flood_get_type();
|
||||
vips_draw_smudge_get_type();
|
||||
}
|
||||
|
||||
/* Fill a scanline between points x1 and x2 inclusive. x1 < x2.
|
||||
|
@ -18,6 +18,8 @@
|
||||
* - deprecate im_smear()
|
||||
* 30/1/12
|
||||
* - back to the custom smear, the conv one was too slow
|
||||
* 11/2/14
|
||||
* - redo as a class
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -56,32 +58,43 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
/**
|
||||
* im_draw_smudge:
|
||||
* @image: image to smudge
|
||||
* @left: area to smudge
|
||||
* @top: area to smudge
|
||||
* @width: area to smudge
|
||||
* @height: area to smudge
|
||||
*
|
||||
* Smudge a section of @image. Each pixel in the area @left, @top, @width,
|
||||
* @height is replaced by the average of the surrounding 3x3 pixels.
|
||||
*
|
||||
* This an inplace operation, so @image is changed. It does not thread and will
|
||||
* not work well as part of a pipeline. On 32-bit machines it will be limited
|
||||
* to 2GB images.
|
||||
*
|
||||
* See also: im_draw_line().
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error.
|
||||
#include "pdraw.h"
|
||||
|
||||
typedef struct _VipsDrawSmudge {
|
||||
VipsDraw parent_object;
|
||||
|
||||
/* Parameters.
|
||||
*/
|
||||
int
|
||||
im_draw_smudge( VipsImage *im, int left, int top, int width, int height )
|
||||
int left;
|
||||
int top;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
} VipsDrawSmudge;
|
||||
|
||||
typedef struct _VipsDrawSmudgeClass {
|
||||
VipsDrawClass parent_class;
|
||||
|
||||
} VipsDrawSmudgeClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsDrawSmudge, vips_draw_smudge, VIPS_TYPE_DRAW );
|
||||
|
||||
static int
|
||||
vips_draw_smudge_build( VipsObject *object )
|
||||
{
|
||||
VipsDraw *draw = VIPS_DRAW( object );
|
||||
VipsImage *im = draw->image;
|
||||
VipsDrawSmudge *smudge = (VipsDrawSmudge *) object;
|
||||
int left = smudge->left;
|
||||
int top = smudge->top;
|
||||
int width = smudge->width;
|
||||
int height = smudge->height;
|
||||
|
||||
/* Double bands for complex images.
|
||||
*/
|
||||
int bands = vips_image_get_bands( im ) *
|
||||
int bands = vips_image_get_bands( draw->image ) *
|
||||
(vips_band_format_iscomplex( vips_image_get_format( im ) ) ?
|
||||
2 : 1);
|
||||
int elements = bands * vips_image_get_width( im );
|
||||
@ -90,6 +103,10 @@ im_draw_smudge( VipsImage *im, int left, int top, int width, int height )
|
||||
double *total;
|
||||
int x, y, i, j, b;
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_draw_smudge_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
area.left = left;
|
||||
area.top = top;
|
||||
area.width = width;
|
||||
@ -107,8 +124,7 @@ im_draw_smudge( VipsImage *im, int left, int top, int width, int height )
|
||||
if( vips_rect_isempty( &clipped ) )
|
||||
return( 0 );
|
||||
|
||||
if( !(total = VIPS_ARRAY( im, bands, double )) ||
|
||||
im_rwcheck( im ) )
|
||||
if( !(total = VIPS_ARRAY( im, bands, double )) )
|
||||
return( -1 );
|
||||
|
||||
/* What we do for each type.
|
||||
@ -163,3 +179,81 @@ im_draw_smudge( VipsImage *im, int left, int top, int width, int height )
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_draw_smudge_class_init( VipsDrawSmudgeClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
vobject_class->nickname = "draw_smudge";
|
||||
vobject_class->description = _( "blur a rectangle on an image" );
|
||||
vobject_class->build = vips_draw_smudge_build;
|
||||
|
||||
VIPS_ARG_INT( class, "left", 6,
|
||||
_( "Left" ),
|
||||
_( "Rect to fill" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsDrawSmudge, left ),
|
||||
-1000000000, 1000000000, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "top", 7,
|
||||
_( "top" ),
|
||||
_( "Rect to fill" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsDrawSmudge, top ),
|
||||
-1000000000, 1000000000, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "width", 8,
|
||||
_( "width" ),
|
||||
_( "Rect to fill" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsDrawSmudge, width ),
|
||||
-1000000000, 1000000000, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "height", 9,
|
||||
_( "height" ),
|
||||
_( "Rect to fill" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsDrawSmudge, height ),
|
||||
-1000000000, 1000000000, 0 );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_draw_smudge_init( VipsDrawSmudge *draw_smudge )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_draw_smudge:
|
||||
* @image: image to draw on
|
||||
* @left: point to paint
|
||||
* @top: point to paint
|
||||
* @width: area to paint
|
||||
* @height: area to paint
|
||||
*
|
||||
* Smudge a section of @image. Each pixel in the area @left, @top, @width,
|
||||
* @height is replaced by the average of the surrounding 3x3 pixels.
|
||||
*
|
||||
* See also: vips_draw_line().
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_draw_smudge( VipsImage *image,
|
||||
int left, int top, int width, int height, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, height );
|
||||
result = vips_call_split( "draw_smudge", ap,
|
||||
image, NULL, left, top, width, height );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
/* base class for drawing operations
|
||||
*
|
||||
* 27/9/10
|
||||
* - from im_draw_circle()
|
||||
* 17/11/10
|
||||
* - oops, scanline clipping was off by 1
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
|
||||
VIPS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
#include "old_draw.h"
|
||||
|
||||
/* Fill a scanline between points x1 and x2 inclusive. x1 < x2.
|
||||
*/
|
||||
void
|
||||
im__draw_scanline( Draw *draw, int y, int x1, int x2 )
|
||||
{
|
||||
VipsPel *mp;
|
||||
int i;
|
||||
int len;
|
||||
|
||||
g_assert( x1 <= x2 );
|
||||
|
||||
if( y < 0 || y >= draw->im->Ysize )
|
||||
return;
|
||||
if( x1 < 0 && x2 < 0 )
|
||||
return;
|
||||
if( x1 >= draw->im->Xsize && x2 >= draw->im->Xsize )
|
||||
return;
|
||||
x1 = IM_CLIP( 0, x1, draw->im->Xsize - 1 );
|
||||
x2 = IM_CLIP( 0, x2, draw->im->Xsize - 1 );
|
||||
|
||||
mp = IM_IMAGE_ADDR( draw->im, x1, y );
|
||||
len = x2 - x1 + 1;
|
||||
|
||||
for( i = 0; i < len; i++ ) {
|
||||
im__draw_pel( draw, mp );
|
||||
mp += draw->psize;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
im__draw_free( Draw *draw )
|
||||
{
|
||||
IM_FREE( draw->ink );
|
||||
}
|
||||
|
||||
Draw *
|
||||
im__draw_init( Draw *draw, IMAGE *im, VipsPel *ink )
|
||||
{
|
||||
if( im_rwcheck( im ) )
|
||||
return( NULL );
|
||||
|
||||
draw->im = im;
|
||||
draw->ink = NULL;
|
||||
|
||||
draw->lsize = IM_IMAGE_SIZEOF_LINE( im );
|
||||
draw->psize = IM_IMAGE_SIZEOF_PEL( im );
|
||||
draw->noclip = FALSE;
|
||||
|
||||
if( ink ) {
|
||||
if( !(draw->ink = (VipsPel *) im_malloc( NULL, draw->psize )) )
|
||||
return( NULL );
|
||||
memcpy( draw->ink, ink, draw->psize );
|
||||
}
|
||||
|
||||
return( draw );
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
/* base class for drawing operations
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
|
||||
VIPS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
/* Our state.
|
||||
*/
|
||||
typedef struct _Draw {
|
||||
/* Parameters.
|
||||
*/
|
||||
IMAGE *im; /* Draw here */
|
||||
VipsPel *ink; /* Copy of ink param */
|
||||
|
||||
/* Derived stuff.
|
||||
*/
|
||||
size_t lsize;
|
||||
size_t psize;
|
||||
|
||||
/* If the object to draw is entirely within the image, we have a
|
||||
* faster noclip path.
|
||||
*/
|
||||
gboolean noclip;
|
||||
} Draw;
|
||||
|
||||
#define DRAW(X) ((Draw *)(X))
|
||||
|
||||
static inline void
|
||||
im__draw_pel( Draw *draw, VipsPel *q )
|
||||
{
|
||||
int j;
|
||||
|
||||
/* Faster than memcopy() for n < about 20.
|
||||
*/
|
||||
for( j = 0; j < draw->psize; j++ )
|
||||
q[j] = draw->ink[j];
|
||||
}
|
||||
|
||||
/* Paint, with clip.
|
||||
*/
|
||||
static inline void
|
||||
im__draw_pel_clip( Draw *draw, int x, int y )
|
||||
{
|
||||
if( x < 0 || x >= draw->im->Xsize )
|
||||
return;
|
||||
if( y < 0 || y >= draw->im->Ysize )
|
||||
return;
|
||||
|
||||
im__draw_pel( draw, IM_IMAGE_ADDR( draw->im, x, y ) );
|
||||
}
|
||||
|
||||
/* Is p painted?
|
||||
*/
|
||||
static inline gboolean
|
||||
im__draw_painted( Draw *draw, VipsPel *p )
|
||||
{
|
||||
int j;
|
||||
|
||||
for( j = 0; j < draw->psize; j++ )
|
||||
if( p[j] != draw->ink[j] )
|
||||
break;
|
||||
|
||||
return( j == draw->psize );
|
||||
}
|
||||
|
||||
void im__draw_scanline( Draw *draw, int y, int x1, int x2 );
|
||||
void im__draw_free( Draw *draw );
|
||||
Draw *im__draw_init( Draw *draw, IMAGE *im, VipsPel *ink );
|
@ -90,10 +90,9 @@ int vips_draw_flood( VipsImage *image, double *ink, int n, int x, int y, ... )
|
||||
int vips_draw_flood1( VipsImage *image, double ink, int x, int y, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
|
||||
|
||||
int im_draw_smudge( VipsImage *image,
|
||||
int left, int top, int width, int height );
|
||||
int vips_draw_smudge( VipsImage *image,
|
||||
int left, int top, int width, int height, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1029,6 +1029,9 @@ int im_draw_flood_other( VipsImage *image, VipsImage *test,
|
||||
int im_draw_point( VipsImage *image, int x, int y, VipsPel *ink );
|
||||
int im_read_point( VipsImage *image, int x, int y, VipsPel *ink );
|
||||
|
||||
int im_draw_smudge( VipsImage *image,
|
||||
int left, int top, int width, int height );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
Loading…
Reference in New Issue
Block a user