| Author | DaveJarvis <email> |
|---|---|
| Date | 2020-09-12 14:31:37 GMT-0700 |
| Commit | a8a443f766a4533a6b65c659f5a81d7045498538 |
| Parent | 20bb20d |
| Delta | 41 lines added, 28 lines removed, 13-line increase |
| import java.net.URL; | ||
| import java.text.NumberFormat; | ||
| -import java.text.ParseException; | ||
| import static com.scrivenvar.graphics.RenderingSettings.RENDERING_HINTS; | ||
| */ | ||
| public class SvgRasterizer { | ||
| - private static final Notifier NOTIFIER = Services.load( Notifier.class ); | ||
| + private static final Notifier sNotifier = Services.load( Notifier.class ); | ||
| private static final SAXSVGDocumentFactory FACTORY_DOM = | ||
| return rasterize( new URL( url ), width ); | ||
| } catch( final Exception e ) { | ||
| - NOTIFIER.notify( e ); | ||
| + notify( e ); | ||
| return BROKEN_IMAGE_PLACEHOLDER; | ||
| } | ||
| * @param xml The SVG xml document. | ||
| * @return The vector graphic transcoded into a raster image format. | ||
| - * @throws TranscoderException Could not convert the vector graphic to an | ||
| - * instance of {@link Image}. | ||
| */ | ||
| - public static BufferedImage rasterizeString( final String xml ) | ||
| - throws IOException, TranscoderException, ParseException { | ||
| - final var doc = toDocument( xml ); | ||
| - final var root = doc.getDocumentElement(); | ||
| - final var width = root.getAttribute( "width" ); | ||
| - return rasterizeString( xml, INT_FORMAT.parse( width ).intValue() ); | ||
| + public static BufferedImage rasterizeString( final String xml ) { | ||
| + try { | ||
| + final var doc = toDocument( xml ); | ||
| + final var root = doc.getDocumentElement(); | ||
| + final var width = root.getAttribute( "width" ); | ||
| + return rasterizeString( xml, INT_FORMAT.parse( width ).intValue() ); | ||
| + } catch( final Exception e ) { | ||
| + notify( e ); | ||
| + return BROKEN_IMAGE_PLACEHOLDER; | ||
| + } | ||
| } | ||
| private static Document toDocument( final String xml ) throws IOException { | ||
| try( final var reader = new StringReader( xml ) ) { | ||
| - return FACTORY_DOM.createSVGDocument( "http://www.w3.org/2000/svg", | ||
| - reader ); | ||
| + return FACTORY_DOM.createSVGDocument( | ||
| + "http://www.w3.org/2000/svg", reader ); | ||
| } | ||
| } | ||
| public static BufferedImage rasterize( final Document svg, final int width ) | ||
| throws TranscoderException { | ||
| final var transcoder = new BufferedImageTranscoder(); | ||
| final var input = new TranscoderInput( svg ); | ||
| - //transcoder.addTranscodingHint( KEY_BACKGROUND_COLOR, WHITE ); | ||
| transcoder.addTranscodingHint( KEY_WIDTH, (float) width ); | ||
| transcoder.transcode( input, null ); | ||
| return writer.toString().replaceAll( "xmlns=\"\" ", "" ); | ||
| } | ||
| + } | ||
| + | ||
| + private static void notify( final Exception e ) { | ||
| + sNotifier.notify( e ); | ||
| } | ||
| } | ||
| import org.xhtmlrenderer.swing.ImageReplacedElement; | ||
| -import javax.imageio.ImageIO; | ||
| import java.awt.image.BufferedImage; | ||
| -import java.io.File; | ||
| import java.util.LinkedHashMap; | ||
| import java.util.Map; | ||
| +import java.util.function.Function; | ||
| -import static com.scrivenvar.graphics.SvgRasterizer.*; | ||
| +import static com.scrivenvar.graphics.SvgRasterizer.rasterize; | ||
| +import static com.scrivenvar.graphics.SvgRasterizer.toSvg; | ||
| /** | ||
| if( SVG_FILE.equalsIgnoreCase( ext ) ) { | ||
| try { | ||
| - image = getImage( src, box.getContentWidth() ); | ||
| + image = getCachedImage( | ||
| + src, svg -> rasterize( svg, box.getContentWidth() ) ); | ||
| } catch( final Exception ex ) { | ||
| - getNotifier().notify( ex ); | ||
| + notify( ex ); | ||
| } | ||
| } | ||
| } | ||
| else if( HTML_SVG.equalsIgnoreCase( nodeName ) ) { | ||
| // Convert the <svg> element to a raster graphic. | ||
| try { | ||
| - //final int width = box.getContentWidth(); | ||
| - final var svg = toSvg( e ); | ||
| - image = rasterizeString( svg ); | ||
| - ImageIO.write( image, "png", new File( "/tmp/svg.png" ) ); | ||
| + final String src = toSvg( e ); | ||
| + image = getCachedImage( src, SvgRasterizer::rasterizeString ); | ||
| } catch( final Exception ex ) { | ||
| - getNotifier().notify( ex ); | ||
| + notify( ex ); | ||
| } | ||
| } | ||
| } | ||
| - private BufferedImage getImage( final String src, final int width ) { | ||
| - return mImageCache.computeIfAbsent( src, v -> rasterize( src, width ) ); | ||
| + /** | ||
| + * Returns an image associated with a string; the string's pre-computed | ||
| + * hash code is returned as the string value, making this operation very | ||
| + * quick to return the corresponding {@link BufferedImage}. | ||
| + * | ||
| + * @param src The SVG used for the key into the image cache. | ||
| + * @param rasterizer {@link Function} to call to convert SVG to an image. | ||
| + * @return The image that corresponds to the given source string. | ||
| + */ | ||
| + private BufferedImage getCachedImage( | ||
| + final String src, final Function<String, BufferedImage> rasterizer ) { | ||
| + return mImageCache.computeIfAbsent( src, v -> rasterizer.apply( src ) ); | ||
| } | ||
| - private Notifier getNotifier() { | ||
| - return sNotifier; | ||
| + private static void notify( final Exception e ) { | ||
| + sNotifier.notify( e ); | ||
| } | ||
| } | ||