Class EmbedAndCrop

java.lang.Object
edu.emory.cellbio.svg.EmbedAndCrop

public class EmbedAndCrop extends Object
Inkscape extension: Embed and Crop Images

This java-based extension for Inkscape facilitates image embedding by:

  • Automatically identifying all linked images.
  • Cropping image data that lies outside the images' clipping frame.
  • Optionally applying jpeg compression.
  • Optionally resampling images.
  • Writing the cropped and possibly compressed image data directly in the SVG file.

By cropping image data that lies outside the clipping frame, applying jpeg compression, or resampling to lower resolution, the resulting file size can be reduced significantly. If preserving image quality is a priority jpeg compression and resampling can be explicitly avoided.

Author:
Benjamin Nanes
  • Field Details

    • imgFileType

      private String imgFileType
    • compQual

      private float compQual
    • doResampling

      private boolean doResampling
    • maxRes

      private double maxRes
  • Constructor Details

    • EmbedAndCrop

      public EmbedAndCrop()
  • Method Details

    • runInkscapeExtension

      public void runInkscapeExtension(String[] args)
      Run the extension
      Parameters:
      args - Command line arguments
      [<input>] [-o <output> | -s] [-t <type> [-q <quality>]] [-r [<resolution>]]
      • <input> Path to the input SVG file. If missing, the user will be presented with a file open dialog box.
      • -o <output> Path to save the output SVG file with embedded images
      • -s Present the user with a file save dialog to specify the output file
        Note: If neither -o nor -s is specified, the output is sent to the standard output stream
      • -t <type> Specify the type of image for encoding. Supported options are png or jpeg. If this is not specified, the user will be presented with a selection dialog.
      • -q <quality> Quality parameter for jpeg compression. Default value is 0.85.
      • -r <resolution> Maximum image resolution, in pixels per mm. Higher resolution images will be downsampled. If this flag is not given, no resampling will be done. If this flag is given, but no resolution is provided, the default value is 11.811, approximately equal to 300dpi.
      Examples:
      input.svg -s -t jpeg -q 0.95
      input.svg -o output.svg
    • runWithoutExit

      public boolean runWithoutExit(String[] args)
      Run the extension, but do not exit the JVM when finished. This method allows an alternate entry point to allow use of the extension programmatically, rather than from Inkscape or the command line.
      See Also:
    • parseArgs

      private void parseArgs(String[] args)
    • process

      private void process(Document dom, String basePath) throws EmbedAndCropException
      Process an SVG DOM
      Throws:
      EmbedAndCropException
    • SVGToStream

      private void SVGToStream(Document dom, OutputStream os) throws EmbedAndCropException
      Push XML(SVG) to a stream
      Throws:
      EmbedAndCropException
    • getOutputParams

      private void getOutputParams() throws EmbedAndCropException
      Harvest output parameters from dialog
      Throws:
      EmbedAndCropException
    • saveAs

      private void saveAs(Document dom) throws EmbedAndCropException
      Save an XML(SVG) file
      Throws:
      EmbedAndCropException
    • save

      private void save(Document dom, File f) throws EmbedAndCropException
      Save an XML(SVG) file
      Throws:
      EmbedAndCropException
    • processImg

      private void processImg(Element img, Element clip, String basePath) throws EmbedAndCropException
      Process an image element
      Throws:
      EmbedAndCropException
    • putImgData

      private void putImgData(Element img, double[] crop, String basePath) throws EmbedAndCropException
      Load image data to embed
      Parameters:
      img - Image element
      crop - Fraction of image to crop from each edge, {top, bottom, left, right}
      Throws:
      EmbedAndCropException
    • adjustImgPlacement

      private void adjustImgPlacement(Element img, double[] crop)
      Adjust placement of the image element to account for cropping
      Parameters:
      img - The image element
      crop - Fraction of image actually cropped from each edge, {top, bottom, left, right}; note that this must account for rounding to pixels
    • limitResolution

      private BufferedImage limitResolution(BufferedImage I, double w, double r)
      Down-sample an image if above a maximum resolution
      Parameters:
      I - Source image
      w - Image width (physical units)
      r - Limiting resolution (pixels per physical unit)
      Returns:
      A resampled image with the lowest possible resolution not less than r, or the source image unchanged if the source image resolution is less than or equal to r.
    • getCropFraction

      private double[] getCropFraction(Element img, Element clip) throws EmbedAndCropException
      Get the fraction of image that should be cropped off each side
      Parameters:
      img - The image element
      clip - The clip-path element
      Returns:
      Fraction of image to crop from each edge, {top, bottom, left, right}
      Throws:
      EmbedAndCropException
    • isPointInRect

      private boolean isPointInRect(double[] p, double[] r)
      Is a point within a rectangle (edges excluded)?
      Parameters:
      p - {x,y}
      r - Bounding points of the rectangle, {x0, x1, y0, y1}
    • distanceFromRect

      private double[] distanceFromRect(double[] p, double[] r)
      How far is a point from each edge of a rectangle?
      Parameters:
      p - {x,y}
      r - Bounding points of the rectangle, {x0, x1, y0, y1}
      Returns:
      Distance from each edge (negative if point is on exterior side of the edge), {top, bottom, left, right}
    • scaleToRectFraction

      private double[] scaleToRectFraction(double[] d, double[] r)
      Scale a set of distances from rectangle edges by the width and height of the rectangle.
      Parameters:
      d - Absolute distances, {top, bottom, left, right}
      r - Bounding points of the rectangle, {x0, x1, y0, y1}
      Returns:
      Relative distances, {top/height, bottom/height, left/width, right/width}
    • distanceFromLine

      private double distanceFromLine(double[] lp0, double[] lp1, double[] x)
      Get the minimum distance between a pont and a line defined by two other points
      Parameters:
      lp0 - 1st point on the line, {x,y}
      lp1 - 2nd point on the line, {x,y}
      x - How far is this point from the line, {x,y}
      Returns:
      Distance of point x from the line
    • getClipPoints

      private double[][] getClipPoints(Element clip) throws EmbedAndCropException
      Extract the coordinates of a clip path
      Returns:
      double[][] coordinates[point]{x,y}
      Throws:
      EmbedAndCropException
    • getPathPointList

      private double[][] getPathPointList(Element path) throws EmbedAndCropException
      Get the points along a path ////Not working
      Returns:
      double[point][{x,y}]
      Throws:
      EmbedAndCropException
    • getRectBounds

      private double[] getRectBounds(Element e)
      Get the boundaries of a rect element (or similar) without transformation
      Returns:
      An array: {x0, x1, y0, y1}
    • rectBoundsToPointList

      private double[][] rectBoundsToPointList(double[] b)
      Convert rect boundary points to a list of corner points
      Parameters:
      b - {x0, x1, y0, y1}, as returned by getRectBounds(org.w3c.dom.Element)
      Returns:
      double[point][{x,y}]
    • transformToDocumentSpace

      private double[] transformToDocumentSpace(double[] point, Node n)
      Transform a point ({x,y}) to document space by recursively looking for transform attributes in the given nodes and all parent nodes.
      Parameters:
      point -
      n -
      Returns:
      {x,y}
    • parseTransform

      private double[] parseTransform(double[] point, String transform)
      Transform a coordinate pair using a transform attribute
      Parameters:
      point - {x,y}
      transform - The transform atribute value
      Returns:
      {x,y}
    • transformMatrix

      private double[] transformMatrix(double[] point, double[] matrix)
      Apply a matrix transformation.

      WARNING - Matrix specification (by row) differs from standard SVG order (by column)

      Parameters:
      point - {x,y}
      matrix - {a,c,e,b,d,f}
      Returns:
      {x,y}
    • transformTranslate

      private double[] transformTranslate(double[] point, double tx, double ty)
      Apply a translation
      Parameters:
      point - {x,y}
      tx - Delta x
      ty - Delta y
      Returns:
      {x,y}
    • transformScale

      private double[] transformScale(double[] point, double sx, double sy)
      Apply a scale
      Parameters:
      point - {x,y}
      sx - x scale factor
      sy - y scale factor
      Returns:
      {x,y}
    • transformRotate

      private double[] transformRotate(double[] point, double a)
      Apply a rotation about the origin
      Parameters:
      point - {x,y}
      a - Angle, in degrees
      Returns:
      {x,y}
    • transformRotate

      private double[] transformRotate(double[] point, double a, double cx, double cy)
      Apply a rotation about center point {cx,cy}
      Parameters:
      point - {x,y}
      a - Angle, in degrees
      Returns:
      {x,y}
    • transformSkewX

      private double[] transformSkewX(double[] point, double a)
      Skew along the x-axis
      Parameters:
      point - {x,y}
      a - Angle, in degrees
      Returns:
      {x,y}
    • transformSkewY

      private double[] transformSkewY(double[] point, double a)
      Skew along the y-axis
      Parameters:
      point - {x,y}
      a - Angle, in degrees
      Returns:
      {x,y}
    • getClipPath

      private Element getClipPath(Element img, Document dom)
      Get the clipping path of an image
    • openDialog

      private File openDialog()
      Get a file using a file open dialog
    • readSVG

      private Document readSVG(File f) throws EmbedAndCropException
      Read an XML file and return a DOM
      Throws:
      EmbedAndCropException
    • test

      public void test() throws EmbedAndCropException
      Throws:
      EmbedAndCropException
    • main

      public static void main(String[] args)