/** * The handler sets the xlink:href tag and returns a transform */ public AffineTransform handleImage(RenderableImage image, Element imageElement, double x, double y, double width, double height, SVGGeneratorContext generatorContext) { double imageWidth = image.getWidth(); double imageHeight = image.getHeight(); if(imageWidth == 0 || imageHeight == 0 || width == 0 || height == 0) { // Forget about it handleEmptyImage(imageElement); } else { imageHandler.handleImage(image, imageElement, generatorContext); setImageAttributes(imageElement, x, y, width, height, generatorContext); } return null; }
/** * Draws a <code>Filter</code> (<code>RenderableImage</code>) into a * Graphics 2D.<p> * * This method also attempts to unwind the rendering chain a bit. * So it knows about certain operations (like affine, pad, * composite), rather than applying each of these operations in * turn it accounts for their affects through modifications to the * Graphics2D. This avoids generating lots of intermediate images. * * @param g2d The Graphics to draw into. * @param filter The filter to draw */ public static void drawImage(Graphics2D g2d, RenderableImage filter) { if (filter instanceof PaintRable) { PaintRable pr = (PaintRable)filter; if (pr.paintRable(g2d)) // paintRable succeeded so we are done... return; } // Get our sources image... // System.out.println("UnOpt: " + filter); AffineTransform at = g2d.getTransform(); RenderedImage ri = filter.createRendering (new RenderContext(at, g2d.getClip(), g2d.getRenderingHints())); if (ri == null) return; g2d.setTransform(IDENTITY); drawImage(g2d, GraphicsUtil.wrap(ri)); g2d.setTransform(at); }
/** * This method will delegate to the <tt>handleHREF</tt> which * uses a <tt>RenderedImage</tt> */ protected void handleHREF(RenderableImage image, Element imageElement, SVGGeneratorContext generatorContext) throws SVGGraphics2DIOException { // Create an buffered image where the image will be drawn Dimension size = new Dimension((int)Math.ceil(image.getWidth()), (int)Math.ceil(image.getHeight())); BufferedImage buf = buildBufferedImage(size); Graphics2D g = createGraphics(buf); g.drawRenderableImage(image, IDENTITY); g.dispose(); handleHREF((RenderedImage)buf, imageElement, generatorContext); }
/** * Draws a <tt>Filter</tt> (<tt>RenderableImage</tt>) into a * Graphics 2D.<p> * * This method also attempts to unwind the rendering chain a bit. * So it knows about certain operations (like affine, pad, * composite), rather than applying each of these operations in * turn it accounts for their affects through modifications to the * Graphics2D. This avoids generating lots of intermediate images. * * @param g2d The Graphics to draw into. * @param filter The filter to draw */ public static void drawImage(Graphics2D g2d, RenderableImage filter) { if (filter instanceof PaintRable) { PaintRable pr = (PaintRable)filter; if (pr.paintRable(g2d)) // paintRable succeeded so we are done... return; } // Get our sources image... // System.out.println("UnOpt: " + filter); AffineTransform at = g2d.getTransform(); RenderedImage ri = filter.createRendering (new RenderContext(at, g2d.getClip(), g2d.getRenderingHints())); if (ri == null) return; g2d.setTransform(IDENTITY); drawImage(g2d, GraphicsUtil.wrap(ri)); g2d.setTransform(at); }
/** * Gets the bounding box for the output of <code>ScaleOpImage</code>. * This method satisfies the implementation of CRIF. */ public Rectangle2D getBounds2D(ParameterBlock paramBlock) { RenderableImage source = paramBlock.getRenderableSource(0); double scaleX = paramBlock.getDoubleParameter(0); double scaleY = paramBlock.getDoubleParameter(1); // Get the source dimensions float x0 = (float)source.getMinX(); float y0 = (float)source.getMinY() ; float w = (float)source.getWidth(); float h = (float)source.getHeight(); // Forward map the source using x0, y0, w and h float d_x0 = (float)(x0 * scaleX); float d_y0 = (float)(y0 * scaleY); float d_w = (float)(w * scaleX); float d_h = (float)(h * scaleY); return new Rectangle2D.Float(d_x0, d_y0, d_w, d_h); }
/** * Gets the bounding box for the output of <code>ScaleOpImage</code>. * This method satisfies the implementation of CRIF. */ public Rectangle2D getBounds2D(ParameterBlock paramBlock) { RenderableImage source = paramBlock.getRenderableSource(0); float scale_x = paramBlock.getFloatParameter(0); float scale_y = paramBlock.getFloatParameter(1); float trans_x = paramBlock.getFloatParameter(2); float trans_y = paramBlock.getFloatParameter(3); Interpolation interp = (Interpolation)paramBlock.getObjectParameter(4); // Get the source dimensions float x0 = (float)source.getMinX(); float y0 = (float)source.getMinY() ; float w = (float)source.getWidth(); float h = (float)source.getHeight(); // Forward map the source using x0, y0, w and h float d_x0 = x0 * scale_x + trans_x; float d_y0 = y0 * scale_y + trans_y; float d_w = w * scale_x; float d_h = h * scale_y; return new Rectangle2D.Float(d_x0, d_y0, d_w, d_h); }
/** * This template method should set the xlink:href attribute on the input * Element parameter */ protected void handleHREF(RenderableImage image, Element imageElement, SVGGeneratorContext generatorContext) throws SVGGraphics2DIOException { // Create an buffered image where the image will be drawn Dimension size = new Dimension((int)Math.ceil(image.getWidth()), (int)Math.ceil(image.getHeight())); BufferedImage buf = buildBufferedImage(size); Graphics2D g = createGraphics(buf); g.drawRenderableImage(image, IDENTITY); g.dispose(); // Save image into file saveBufferedImageToFile(imageElement, buf, generatorContext); }
/** * The handler should set the xlink:href tag and the width and * height attributes. */ public void handleHREF(RenderableImage image, Element imageElement, SVGGeneratorContext generatorContext) throws SVGGraphics2DIOException { if (image == null){ throw new SVGGraphics2DRuntimeException(ERR_IMAGE_NULL); } RenderedImage r = image.createDefaultRendering(); if (r == null) { handleEmptyImage(imageElement); } else { handleHREF(r, imageElement, generatorContext); } }
/** * The handler sets the xlink:href tag and returns a transform */ public AffineTransform handleImage(RenderableImage image, Element imageElement, double x, double y, double width, double height, SVGGeneratorContext generatorContext) { double imageWidth = image.getWidth(); double imageHeight = image.getHeight(); AffineTransform af = null; if(imageWidth == 0 || imageHeight == 0 || width == 0 || height == 0) { // Forget about it handleEmptyImage(imageElement); } else { // First set the href try { handleHREF(image, imageElement, generatorContext); } catch (SVGGraphics2DIOException e) { try { generatorContext.errorHandler.handleError(e); } catch (SVGGraphics2DIOException io) { // we need a runtime exception because // java.awt.Graphics2D method doesn't throw exceptions.. throw new SVGGraphics2DRuntimeException(io); } } // Then create the transformation: // Because we cache image data, the stored image may // need to be scaled. af = handleTransform(imageElement, x,y, imageWidth, imageHeight, width, height, generatorContext); } return af; }
/** * This method will delegate to the <code>handleHREF</code> which * uses a <code>RenderedImage</code> */ protected void handleHREF(RenderableImage image, Element imageElement, SVGGeneratorContext generatorContext) throws SVGGraphics2DIOException { // Create an buffered image where the image will be drawn Dimension size = new Dimension((int)Math.ceil(image.getWidth()), (int)Math.ceil(image.getHeight())); BufferedImage buf = buildBufferedImage(size); Graphics2D g = createGraphics(buf); g.drawRenderableImage(image, IDENTITY); g.dispose(); handleHREF((RenderedImage)buf, imageElement, generatorContext); }
/** * The handler should set the xlink:href tag and the width and * height attributes. */ public void handleImage(RenderableImage image, Element imageElement, SVGGeneratorContext generatorContext) { // // First, set the image width and height // imageElement.setAttributeNS(null, SVG_WIDTH_ATTRIBUTE, String.valueOf( image.getWidth() ) ); imageElement.setAttributeNS(null, SVG_HEIGHT_ATTRIBUTE, String.valueOf( image.getHeight() ) ); // // Now, set the href // try { handleHREF(image, imageElement, generatorContext); } catch (SVGGraphics2DIOException e) { try { generatorContext.errorHandler.handleError(e); } catch (SVGGraphics2DIOException io) { // we need a runtime exception because // java.awt.Graphics2D method doesn't throw exceptions.. throw new SVGGraphics2DRuntimeException(io); } } }
/** * This returns true if <code>ri</code> and all of <code>ri</code>'s * sources implement the PaintRable interface. This is used to * indicate that the chain has a good potential for bypassing the * filterRes operation entirely. * * Ideally there would be a checkPaintRable method in PaintRable * that could be used to get a definate answer about a filters * ability to draw directly to a Graphics2D (this can sometimes * 'fail' because of the way the Graphics2D is currently * configured). */ public boolean allPaintRable(RenderableImage ri) { if (!(ri instanceof PaintRable)) return false; List v = ri.getSources(); // No sources and we are PaintRable so the chain is PaintRable. if (v == null) return true; Iterator i = v.iterator(); while (i.hasNext()) { RenderableImage nri = (RenderableImage)i.next(); // A source is not paintRable so we are not 100% paintRable. if (!allPaintRable(nri)) return false; } return true; }
public String [] getPropertyNames() { Set keys = props.keySet(); Iterator iter = keys.iterator(); String[] ret = new String[keys.size()]; int i=0; while (iter.hasNext()) { ret[i++] = (String)iter.next(); } iter = srcs.iterator(); while (iter.hasNext()) { RenderableImage ri = (RenderableImage)iter.next(); String [] srcProps = ri.getPropertyNames(); if (srcProps.length != 0) { String [] tmp = new String[ret.length+srcProps.length]; System.arraycopy(ret,0,tmp,0,ret.length); System.arraycopy(tmp,ret.length,srcProps,0,srcProps.length); ret = tmp; } } return ret; }
/** * Draws a <code>Filter</code> (<code>RenderableImage</code>) into a * Graphics 2D after taking into account a particular * <code>RenderContext</code>.<p> * * This method also attempts to unwind the rendering chain a bit. * So it knows about certain operations (like affine, pad, * composite), rather than applying each of these operations in * turn it accounts for their affects through modifications to the * Graphics2D. This avoids generating lots of intermediate images. * * @param g2d The Graphics to draw into. * @param filter The filter to draw * @param rc The render context that controls the drawing operation. */ public static void drawImage(Graphics2D g2d, RenderableImage filter, RenderContext rc) { AffineTransform origDev = g2d.getTransform(); Shape origClip = g2d.getClip(); RenderingHints origRH = g2d.getRenderingHints(); Shape clip = rc.getAreaOfInterest(); if (clip != null) g2d.clip(clip); g2d.transform(rc.getTransform()); g2d.setRenderingHints(rc.getRenderingHints()); drawImage(g2d, filter); g2d.setTransform(origDev); g2d.setClip(origClip); g2d.setRenderingHints(origRH); }
/** * Renders a renderable image. This produces a RenderedImage, which is * then passed to {@link #drawRenderedImage(RenderedImage, AffineTransform)} * to perform the final rendering. * * @param image the renderable image to be rendered * @param xform the transform from image space to user space */ public void drawRenderableImage(RenderableImage image, AffineTransform xform) { Rectangle areaOfInterest = new Rectangle((int) image.getMinX(), (int) image.getHeight(), (int) image.getWidth(), (int) image.getHeight()); drawRenderableImageImpl(image, xform, areaOfInterest); }
/** * Inline a referenced thumbnail. * * @param doc Document (element factory) * @param urldata URL * @param eold Existing node * @return Replacement node, or {@code null} */ protected Node inlineThumbnail(Document doc, ParsedURL urldata, Node eold) { RenderableImage img = ThumbnailRegistryEntry.handleURL(urldata); if(img == null) { LoggingUtil.warning("Image not found in registry: " + urldata.toString()); return null; } ByteArrayOutputStream os = new ByteArrayOutputStream(); try { os.write(SVGSyntax.DATA_PROTOCOL_PNG_PREFIX.getBytes()); Base64EncoderStream encoder = new Base64EncoderStream(os); ImageIO.write(img.createDefaultRendering(), "png", encoder); encoder.close(); } catch(IOException e) { LoggingUtil.exception("Exception serializing image to png", e); return null; } Element i = (Element) super.cloneNode(doc, eold); i.setAttributeNS(SVGConstants.XLINK_NAMESPACE_URI, SVGConstants.XLINK_HREF_ATTRIBUTE, os.toString().replaceAll("\\s*[\\r\\n]+\\s*", "")); return i; }
/** * Draws the renderable image. * * @param img the renderable image. * @param xform the transform. */ @Override public void drawRenderableImage(RenderableImage img, AffineTransform xform) { RenderedImage ri = img.createDefaultRendering(); drawRenderedImage(ri, xform); }
/** * This returns true if <tt>ri</tt> and all of <tt>ri</tt>'s * sources implement the PaintRable interface. This is used to * indicate that the chain has a good potential for bypassing the * filterRes operation entirely. * * Ideally there would be a checkPaintRable method in PaintRable * that could be used to get a definate answer about a filters * ability to draw directly to a Graphics2D (this can sometimes * 'fail' because of the way the Graphics2D is currently * configured). */ public boolean allPaintRable(RenderableImage ri) { if (!(ri instanceof PaintRable)) return false; List v = ri.getSources(); // No sources and we are PaintRable so the chain is PaintRable. if (v == null) return true; Iterator i = v.iterator(); while (i.hasNext()) { RenderableImage nri = (RenderableImage)i.next(); // A source is not paintRable so we are not 100% paintRable. if (!allPaintRable(nri)) return false; } return true; }
/** * Draws a <tt>Filter</tt> (<tt>RenderableImage</tt>) into a * Graphics 2D after taking into account a particular * <tt>RenderContext</tt>.<p> * * This method also attempts to unwind the rendering chain a bit. * So it knows about certain operations (like affine, pad, * composite), rather than applying each of these operations in * turn it accounts for their affects through modifications to the * Graphics2D. This avoids generating lots of intermediate images. * * @param g2d The Graphics to draw into. * @param filter The filter to draw * @param rc The render context that controls the drawing operation. */ public static void drawImage(Graphics2D g2d, RenderableImage filter, RenderContext rc) { AffineTransform origDev = g2d.getTransform(); Shape origClip = g2d.getClip(); RenderingHints origRH = g2d.getRenderingHints(); Shape clip = rc.getAreaOfInterest(); if (clip != null) g2d.clip(clip); g2d.transform(rc.getTransform()); g2d.setRenderingHints(rc.getRenderingHints()); drawImage(g2d, filter); g2d.setTransform(origDev); g2d.setClip(origClip); g2d.setRenderingHints(origRH); }
/** * Maps the output RenderContext into the RenderContext for the ith * source. * This method satisfies the implementation of CRIF. * * @param i The index of the source image. * @param renderContext The renderContext being applied to the operation. * @param paramBlock The ParameterBlock containing the sources * and the translation factors. * @param image The RenderableImageOp from which this method * was called. */ public RenderContext mapRenderContext(int i, RenderContext renderContext, ParameterBlock paramBlock, RenderableImage image) { float x_center = paramBlock.getFloatParameter(0); float y_center = paramBlock.getFloatParameter(1); float angle = paramBlock.getFloatParameter(2); AffineTransform rotate = AffineTransform.getRotateInstance(angle, x_center, y_center); RenderContext RC = (RenderContext)renderContext.clone(); AffineTransform usr2dev = RC.getTransform(); usr2dev.concatenate(rotate); RC.setTransform(usr2dev); return RC; }
/** * Maps the output RenderContext into the RenderContext for the ith * source. * This method satisfies the implementation of CRIF. * * @param i The index of the source image. * @param renderContext The renderContext being applied to the operation. * @param paramBlock The ParameterBlock containing the sources * and the translation factors. * @param image The RenderableImageOp from which this method * was called. */ public RenderContext mapRenderContext(int i, RenderContext renderContext, ParameterBlock paramBlock, RenderableImage image) { double scaleX = paramBlock.getDoubleParameter(0); double scaleY = paramBlock.getDoubleParameter(1); AffineTransform scale = new AffineTransform(scaleX, 0.0, 0.0, scaleY, 0.0, 0.0); RenderContext RC = (RenderContext)renderContext.clone(); AffineTransform usr2dev = RC.getTransform(); usr2dev.concatenate(scale); RC.setTransform(usr2dev); return RC; }
/** * Gets the output bounding box in rendering-independent space. * This method satisfies the implementation of CRIF. */ public Rectangle2D getBounds2D(ParameterBlock paramBlock) { RenderableImage mres = createRenderable(paramBlock); return new Rectangle2D.Float(mres.getMinX(), mres.getMinY(), mres.getWidth(), mres.getHeight()); }
/** * Creates a <Code>RenderedImage</Code> from the renderable layer. * * @param renderContext The rendering information associated with * this rendering. * @param paramBlock The parameters used to create the image. * @return A <code>RenderedImage</code>. */ public RenderedImage create(RenderContext renderContext, ParameterBlock paramBlock) { // Get the two renderable alpha images from the parameter block RenderableImage alphaImage1 = (RenderableImage)paramBlock.getObjectParameter(0); RenderableImage alphaImage2 = (RenderableImage)paramBlock.getObjectParameter(1); // Cause the two renderable alpha images to be rendered RenderedImage rAlphaImage1 = alphaImage1.createRendering(renderContext); RenderedImage rAlphaImage2 = alphaImage2.createRendering(renderContext); ParameterBlock newPB = (ParameterBlock)paramBlock.clone(); // Replace the renderable alpha images in the ParameterBlock with // their renderings newPB.set(rAlphaImage1, 0); newPB.set(rAlphaImage2, 1); // Return JAI.create("composite") return JAI.create("composite", newPB, renderContext.getRenderingHints()); }