示例#1
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%     A f f i n e T r a n s f o r m I m a g e                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  AffineTransformImage() transforms an image as dictated by the affine matrix.
%  It allocates the memory necessary for the new Image structure and returns
%  a pointer to the new image.
%
%  The format of the AffineTransformImage method is:
%
%      Image *AffineTransformImage(const Image *image,
%        AffineMatrix *affine,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image: The image.
%
%    o affine: The affine transform.
%
%    o exception: Return any errors or warnings in this structure.
%
%
*/
MagickExport Image *AffineTransformImage(const Image *image,
  const AffineMatrix *affine,ExceptionInfo *exception)
{
  AffineMatrix
    transform;

  Image
    *affine_image;

  long
    y;

  PointInfo
    extent[4],
    min,
    max;

  register long
    i,
    x;

  /*
    Determine bounding box.
  */
  assert(image != (const Image *) NULL);
  assert(image->signature == MagickSignature);
  assert(affine != (AffineMatrix *) NULL);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  extent[0].x=0;
  extent[0].y=0;
  extent[1].x=image->columns;
  extent[1].y=0;
  extent[2].x=image->columns;
  extent[2].y=image->rows;
  extent[3].x=0;
  extent[3].y=image->rows;
  for (i=0; i < 4; i++)
  {
    x=(long) (extent[i].x+0.5);
    y=(long) (extent[i].y+0.5);
    extent[i].x=x*affine->sx+y*affine->ry+affine->tx;
    extent[i].y=x*affine->rx+y*affine->sy+affine->ty;
  }
  min=extent[0];
  max=extent[0];
  for (i=1; i < 4; i++)
  {
    if (min.x > extent[i].x)
      min.x=extent[i].x;
    if (min.y > extent[i].y)
      min.y=extent[i].y;
    if (max.x < extent[i].x)
      max.x=extent[i].x;
    if (max.y < extent[i].y)
      max.y=extent[i].y;
  }
  /*
    Affine transform image.
  */
  affine_image=CloneImage(image,(unsigned long) ceil(max.x-min.x-0.5),
    (unsigned long) ceil(max.y-min.y-0.5),True,exception);
  if (affine_image == (Image *) NULL)
    return((Image *) NULL);
  (void) SetImage(affine_image,TransparentOpacity);
  transform.sx=affine->sx;
  transform.rx=affine->rx;
  transform.ry=affine->ry;
  transform.sy=affine->sy;
  transform.tx=(-min.x);
  transform.ty=(-min.y);
  (void) DrawAffineImage(affine_image,image,&transform);
  return(affine_image);
}
示例#2
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%     A f f i n e T r a n s f o r m I m a g e                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  AffineTransformImage() transforms an image as dictated by the affine matrix.
%  It allocates the memory necessary for the new Image structure and returns
%  a pointer to the new image.
%
%  The format of the AffineTransformImage method is:
%
%      Image *AffineTransformImage(const Image *image,
%        AffineMatrix *affine_matrix,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image: the image.
%
%    o affine_matrix: the affine matrix.
%
%    o exception: Return any errors or warnings in this structure.
%
*/
MagickExport Image *AffineTransformImage(const Image *image,
  const AffineMatrix *affine_matrix,ExceptionInfo *exception)
{
  AffineMatrix
    transform;

  Image
    *affine_image;

  PointInfo
    extent[4],
    min,
    max,
    point;

  register long
    i;

  assert(image != (const Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  assert(affine_matrix != (AffineMatrix *) NULL);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  /*
    Determine destination image bounding box.
  */
  extent[0].x=(double) image->page.x;
  extent[0].y=(double) image->page.y;
  extent[1].x=(double) (image->page.x+image->columns);
  extent[1].y=(double) image->page.y;
  extent[2].x=(double) (image->page.x+image->columns);
  extent[2].y=(double) (image->page.y+image->rows);
  extent[3].x=(double) image->page.x;
  extent[3].y=(double) (image->page.y+image->rows);
  for (i=0; i < 4; i++)
  {
    point=extent[i];
    extent[i].x=(double) (point.x*affine_matrix->sx+point.y*affine_matrix->ry+
      affine_matrix->tx);
    extent[i].y=(double) (point.x*affine_matrix->rx+point.y*affine_matrix->sy+
      affine_matrix->ty);
  }
  min=extent[0];
  max=extent[0];
  for (i=1; i < 4; i++)
  {
    if (min.x > extent[i].x)
      min.x=extent[i].x;
    if (min.y > extent[i].y)
      min.y=extent[i].y;
    if (max.x < extent[i].x)
      max.x=extent[i].x;
    if (max.y < extent[i].y)
      max.y=extent[i].y;
  }
  affine_image=CloneImage(image,(unsigned long) (max.x-min.x+0.5),
    (unsigned long) (max.y-min.y+0.5),MagickTrue,exception);
  if (affine_image == (Image *) NULL)
    return((Image *) NULL);
  affine_image->background_color.opacity=(Quantum) TransparentOpacity;
  (void) SetImageBackgroundColor(affine_image);
  /*
    Adjust transform translation for direct image to image transformation.
    That is, pixel 0,0 translates correctly to its location in destination.
  */
  transform=(*affine_matrix);
  transform.tx=extent[0].x-min.x;
  transform.ty=extent[0].y-min.y;
  /*
    Affine transform image.
  */
  (void) DrawAffineImage(affine_image,image,&transform);
  /*
    Add offset to resulting image.
  */
  affine_image->page.x=(long) floor(min.x+0.5);
  affine_image->page.y=(long) floor(min.y+0.5);
  /*
    Roughly calculate an appropriate virtual canvas (page) size.
  */
  affine_image->page.width=affine_image->columns;
  if (affine_image->page.x > 0)
    affine_image->page.width+=affine_image->page.x;
  affine_image->page.height=affine_image->rows;
  if (affine_image->page.y > 0)
    affine_image->page.height+=affine_image->page.y;
  return(affine_image);
}
示例#3
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%     A f f i n e T r a n s f o r m I m a g e                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  AffineTransformImage() transforms an image as dictated by the affine matrix.
%  It allocates the memory necessary for the new Image structure and returns
%  a pointer to the new image.
%
%  The format of the AffineTransformImage method is:
%
%      Image *AffineTransformImage(const Image *image,AffineMatrix *affine,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image: The image.
%
%    o affine: The affine transform.
%
%    o exception: Return any errors or warnings in this structure.
%
%
*/
MagickExport Image *AffineTransformImage(const Image *image,
  const AffineMatrix *affine,ExceptionInfo *exception)
{
  AffineMatrix
    transform;

  Image
    *affine_image;

  PointInfo
    extent[4],
    min,
    max,
    point;

  register long
    i;

  /*
    Determine bounding box.
  */
  assert(image != (const Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  assert(affine != (AffineMatrix *) NULL);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  extent[0].x=0.0;
  extent[0].y=0.0;
  extent[1].x=(double) image->columns;
  extent[1].y=0.0;
  extent[2].x=(double) image->columns;
  extent[2].y=(double) image->rows;
  extent[3].x=0.0;
  extent[3].y=(double) image->rows;
  for (i=0; i < 4; i++)
  {
    point=extent[i];
    extent[i].x=(double) (point.x*affine->sx+point.y*affine->ry+affine->tx);
    extent[i].y=(double) (point.x*affine->rx+point.y*affine->sy+affine->ty);
  }
  min=extent[0];
  max=extent[0];
  for (i=1; i < 4; i++)
  {
    if (min.x > extent[i].x)
      min.x=extent[i].x;
    if (min.y > extent[i].y)
      min.y=extent[i].y;
    if (max.x < extent[i].x)
      max.x=extent[i].x;
    if (max.y < extent[i].y)
      max.y=extent[i].y;
  }
  /*
    Affine transform image.
  */
  affine_image=CloneImage(image,(unsigned long) (max.x-min.x+0.5),
    (unsigned long) (max.y-min.y+0.5),MagickTrue,exception);
  if (affine_image == (Image *) NULL)
    return((Image *) NULL);
  affine_image->background_color.opacity=TransparentOpacity;
  SetImageBackgroundColor(affine_image);
  transform.sx=affine->sx;
  transform.rx=affine->rx;
  transform.ry=affine->ry;
  transform.sy=affine->sy;
  transform.tx=min.x;
  transform.ty=min.y;
  (void) DrawAffineImage(affine_image,image,&transform);
  return(affine_image);
}