You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-users@xmlgraphics.apache.org by "Warren W. Thompson" <wt...@altaira.com> on 2001/12/17 21:36:25 UTC
Render SVG as a BufferedImage
I am attempting to render an SVG image file as a java.awt.Image, or one
of its subclasses like java.awt.image.BufferedImage. I have attempted to
directly render the SVG file and I have also attempted to transcode it.
I am currently using Batik version 1.1.
I have achieved the most success with the following code snippet; however,
the BufferedImage that is returned is the correct shape without any colors
or details being drawn. I feel that I am missing some step in the rendering
process, and I have looked in detail at the Batik documentation and mailing
list archives to no avail.
public static Image renderSVGDocument( URL url, int x, int y ){
// Create a rendereing context.
UserAgent userAgent = new UserAgentAdapter();
DocumentLoader loader = new DocumentLoader( userAgent );
Document doc = null;
try {
doc = loader.loadDocument( url.toString() );
} catch( Exception ex ){
ex.printStackTrace();
}
BridgeContext ctx = new BridgeContext(userAgent, loader);
// Create a buffered image.
BufferedImage bufImg =
new BufferedImage( x, y, BufferedImage.TYPE_INT_ARGB );
Graphics2D graphics = GraphicsUtil.createGraphics( bufImg );
// Create a builder and root node.
GVTBuilder builder = new GVTBuilder();
GraphicsNode root = null;
// Render the SVG image.
try {
root = builder.build(ctx, doc);
root.paint(graphics);
} catch (Exception e) {
e.printStackTrace();
}
return bufImg;
}
Thanks in advance for your assistance!
Warren W. Thompson
Beer is proof that God loves us and wants us to be happy.
--Benjamin Franklin
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org
Re: Embed a Swing Component in an JSVGCanvas
Posted by Thomas E Deweese <th...@kodak.com>.
>>>>> "WT" == Warren W Thompson <wt...@altaira.com> writes:
WT> [...] I have read about the SVG foreignObject element and I am
WT> wondering if it is proper to integrate that with the proposed
WT> embedded Swing tag. [...]
WT> Is this the correct approach to solving this sort of problem?
It looked pretty good to me but I'll let Thierry answer that one.
WT> If so, how do I proceed to tell Batik about the extension with the
WT> URI http://mydomain.com/SVGExtenstions/BatikSwing ?
Read:
http://xml.apache.org/batik/extendingBatik.html
xml-batik/sources/org/apache/batik/extension/svg/BatikBridgeExtension.java.
When you add your tag to the bridge (see BridgeExtension). by
implementing the BridgeExtension interface one of the methods is
'getImplementedExtensions'. The returned iterator should have your
extension URI in it.
Good luck.
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org
Re: Embed a Swing Component in an JSVGCanvas
Posted by "Warren W. Thompson" <wt...@altaira.com>.
Sorry to ask so many questions, but I am relatively new to SVG development.
I have read about the SVG foreignObject element and I am wondering if
it is proper to integrate that with the proposed embedded Swing tag. I
am not exactly sure how the foreignObject element is intended to be
used. There is an example in the SVG specification, but it is relatively
simplistic. So, if I were to use the foreignObject element, in
combination with the switch element as described in the specification,
would it look something like this?
<switch>
<!-- Draw the JButton here is the extension to Batik is available. -->
<foreignObject width="100" height="50"
requiredExtensions="http://mydomain.com/SVGExtenstions/BatikSwing">
<batikSwing:javaAWTComponent
style="class:javax.swing.JButton;foreground:red;text:Click Here"/>
</foreignObject>
<!-- Draw a red rectangle with an error message to indicate -->
<!-- the the JButton could not be rendered. -->
<g>
<rect width="100" height="50" style="fill:red"/>
<text>JButton Goes Here.</text>
</g>
</switch>
Is this the correct approach to solving this sort of problem?
If so, how do I proceed to tell Batik about the extension with the URI
http://mydomain.com/SVGExtenstions/BatikSwing ?
Thanks again,
Warren
Beer is proof that God loves us and wants us to be happy.
--Benjamin Franklin
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org
Re: Embed a Swing Component in an JSVGCanvas
Posted by Thierry Kormann <tk...@ilog.fr>.
On Monday 07 January 2002 21:06, Warren W. Thompson wrote:
> Thank you pointing me in the right direction Thierry! :)
>
> I would like something a little more generic than creating a different
> SVG element for every Swing component. I think it might be possible to
> make something like...
>
> <batikSwing:awtComponent style="class:javax.swing.JButton;foreground:red"
> .../>
>
> ...so that all of the existing Swing components would be available,
> as well as any custom components that a developer may have created.
>
> Does this sort of approach sound feasible?
absolutely.
Swing components are JavaBeans so introspection is easy to do to set
properties and instantiate your class.
Thierry.
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org
Re: Embed a Swing Component in an JSVGCanvas
Posted by "Warren W. Thompson" <wt...@altaira.com>.
Thank you pointing me in the right direction Thierry! :)
I would like something a little more generic than creating a different
SVG element for every Swing component. I think it might be possible to
make something like...
<batikSwing:awtComponent style="class:javax.swing.JButton;foreground:red" .../>
...so that all of the existing Swing components would be available,
as well as any custom components that a developer may have created.
Does this sort of approach sound feasible?
Are any plans to integrate the ability to embed Swing components into
the Batik source code?
Are there any concrete examples of embedding a Swing, or AWT, component
in a Batik canvas? (I must admit to having a little difficulty creating
my own custom SVG element to support this functionality.)
Thanks again for all of your help!
Warren
Beer is proof that God loves us and wants us to be happy.
--Benjamin Franklin
Thierry Kormann wrote:
>
> On Thursday 20 December 2001 16:03, Warren W. Thompson wrote:
> > Is it possible to embed Swing components, like a JTextField, inside of
> > an SVG file being shown in a JSVGCanvas? The closest thing that I found
> > on the Batik Web site was the section that deals with 'Extensions' to the
> > SVG XML. Has anyone successfully done something like this?
>
> I manage to include swing component inside SVG using extensions. What have
> done is:
>
> - a custom SwingGraphicsNode that extends AbstractGaphicsNode and delegates
> to an enclosed swing component the primitive paint (basically, the GVT's
> primitivePaint calls the paintComponent methods).
>
> - a custom bridge that builds this SwingGraphicsNode (through elements such
> as: <batikSwing:jbutton ...>
>
> Then, you have swing inside JSVGCanvas through SVG syntax. The problem now
> (much more difficult) is to handle events properly and repaint the widget if
> necessary.
>
> repaint could be done when batik will be dynamique, events are trickier.
>
> Good luck.
> Thierry.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
> For additional commands, e-mail: batik-users-help@xml.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org
Re: Embed a Swing Component in an JSVGCanvas
Posted by Thierry Kormann <tk...@ilog.fr>.
On Thursday 20 December 2001 16:03, Warren W. Thompson wrote:
> Is it possible to embed Swing components, like a JTextField, inside of
> an SVG file being shown in a JSVGCanvas? The closest thing that I found
> on the Batik Web site was the section that deals with 'Extensions' to the
> SVG XML. Has anyone successfully done something like this?
I manage to include swing component inside SVG using extensions. What have
done is:
- a custom SwingGraphicsNode that extends AbstractGaphicsNode and delegates
to an enclosed swing component the primitive paint (basically, the GVT's
primitivePaint calls the paintComponent methods).
- a custom bridge that builds this SwingGraphicsNode (through elements such
as: <batikSwing:jbutton ...>
Then, you have swing inside JSVGCanvas through SVG syntax. The problem now
(much more difficult) is to handle events properly and repaint the widget if
necessary.
repaint could be done when batik will be dynamique, events are trickier.
Good luck.
Thierry.
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org
Embed a Swing Component in an JSVGCanvas
Posted by "Warren W. Thompson" <wt...@altaira.com>.
Is it possible to embed Swing components, like a JTextField, inside of
an SVG file being shown in a JSVGCanvas? The closest thing that I found
on the Batik Web site was the section that deals with 'Extensions' to the
SVG XML. Has anyone successfully done something like this?
Thanks,
Warren W. Thompson
Beer is proof that God loves us and wants us to be happy.
--Benjamin Franklin
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org
Re: Render SVG as a BufferedImage
Posted by Thierry Kormann <tk...@ilog.fr>.
On Thursday 20 December 2001 16:16, Thierry Kormann wrote:
>
> The following code is not really optimal as you encode the image in png and
> then decode it. Another way to implement that would be to subclass the
> ImageTranscoder such as (live code so might not work :):
>
> import org.apache.batik.transcoder.*;
> import org.apache.batik.transcoder.image.ImageTranscoder;
>
> public class Foo {
>
> public static Image transcodeSVGDocument( URL url, int x, int y ){
>
> // Create a custom transcoder.
MyImageTranscoder t = new MyImageTranscoder();
>
> // Set the transcoding hints.
> t.addTranscodingHint( PNGTranscoder.KEY_WIDTH, new Float(x) );
> t.addTranscodingHint( PNGTranscoder.KEY_HEIGHT, new Float(y) );
>
> // Create the transcoder input.
> TranscoderInput input = new TranscoderInput( url.toString() );
> t.transcode(input, null);
>
> return t.getBufferedImage();
> }
>
> static class MyImageTranscoder extends ImageTranscoder {
>
> protected BufferedImage img;
>
> public void writeImage(BufferedImage img, TranscoderOutput output)
> throws TranscoderException {
> this.img = img; // just store the image
> }
>
> public BufferedImage getBufferedImage() {
> return img;
> }
> }
> }
>
PS: Still live code :)
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org
Re: Render SVG as a BufferedImage
Posted by Thierry Kormann <tk...@ilog.fr>.
On Thursday 20 December 2001 15:44, Warren W. Thompson wrote:
> Thanks for pointing me in the right direction Vincent! I've attached
> the working code for converting an SVG file into a java.awt.Image below
> for posterity.
>
> public static Image transcodeSVGDocument( URL url, int x, int y ){
> // Create a PNG transcoder.
> Transcoder t = new PNGTranscoder();
>
> // Set the transcoding hints.
> t.addTranscodingHint( PNGTranscoder.KEY_WIDTH, new Float(x) );
> t.addTranscodingHint( PNGTranscoder.KEY_HEIGHT, new Float(y) );
>
> // Create the transcoder input.
> TranscoderInput input = new TranscoderInput( url.toString() );
>
> ByteArrayOutputStream ostream = null;
> try {
> // Create the transcoder output.
> ostream = new ByteArrayOutputStream();
> TranscoderOutput output = new TranscoderOutput( ostream );
>
> // Save the image.
> t.transcode( input, output );
>
> // Flush and close the stream.
> ostream.flush();
> ostream.close();
> } catch( Exception ex ){
> ex.printStackTrace();
> }
>
> // Convert the byte stream into an image.
> byte[] imgData = ostream.toByteArray();
> Image img = Toolkit.getDefaultToolkit().createImage( imgData );
>
> // Wait until the entire image is loaded.
> MediaTracker tracker = new MediaTracker( new JPanel() );
> tracker.addImage( img, 0 );
> try {
> tracker.waitForID( 0 );
> } catch( InterruptedException ex ){
> ex.printStackTrace();
> }
>
> // Return the newly rendered image.
> return img;
> }
The following code is not really optimal as you encode the image in png and
then decode it. Another way to implement that would be to subclass the
ImageTranscoder such as (live code so might not work :):
import org.apache.batik.transcoder.*;
import org.apache.batik.transcoder.image.ImageTranscoder;
public class Foo {
public static Image transcodeSVGDocument( URL url, int x, int y ){
// Create a custom transcoder.
Transcoder t = new MyImageTranscoder();
// Set the transcoding hints.
t.addTranscodingHint( PNGTranscoder.KEY_WIDTH, new Float(x) );
t.addTranscodingHint( PNGTranscoder.KEY_HEIGHT, new Float(y) );
// Create the transcoder input.
TranscoderInput input = new TranscoderInput( url.toString() );
t.transcode(input, null);
return t.getBufferedImage();
}
static class MyImageTranscoder extends ImageTranscoder {
protected BufferedImage img;
public void writeImage(BufferedImage img, TranscoderOutput output)
throws TranscoderException {
this.img = img; // just store the image
}
public BufferedImage getBufferedImage() {
return img;
}
}
}
Thierry.
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org
Re: Render SVG as a BufferedImage
Posted by "Warren W. Thompson" <wt...@altaira.com>.
Thanks for pointing me in the right direction Vincent! I've attached
the working code for converting an SVG file into a java.awt.Image below
for posterity.
public static Image transcodeSVGDocument( URL url, int x, int y ){
// Create a PNG transcoder.
Transcoder t = new PNGTranscoder();
// Set the transcoding hints.
t.addTranscodingHint( PNGTranscoder.KEY_WIDTH, new Float(x) );
t.addTranscodingHint( PNGTranscoder.KEY_HEIGHT, new Float(y) );
// Create the transcoder input.
TranscoderInput input = new TranscoderInput( url.toString() );
ByteArrayOutputStream ostream = null;
try {
// Create the transcoder output.
ostream = new ByteArrayOutputStream();
TranscoderOutput output = new TranscoderOutput( ostream );
// Save the image.
t.transcode( input, output );
// Flush and close the stream.
ostream.flush();
ostream.close();
} catch( Exception ex ){
ex.printStackTrace();
}
// Convert the byte stream into an image.
byte[] imgData = ostream.toByteArray();
Image img = Toolkit.getDefaultToolkit().createImage( imgData );
// Wait until the entire image is loaded.
MediaTracker tracker = new MediaTracker( new JPanel() );
tracker.addImage( img, 0 );
try {
tracker.waitForID( 0 );
} catch( InterruptedException ex ){
ex.printStackTrace();
}
// Return the newly rendered image.
return img;
}
Warren W. Thompson
Beer is proof that God loves us and wants us to be happy.
--Benjamin Franklin
Vincent Hardy wrote:
>
> Warren,
>
> The org.apache.batik.transcoder.image.ImageTranscoder class should
> be exactly what you want. If you are trying to convert images to
> PNG or JPEG, you may even be able to use the PNGTranscoder or the
> JPEGTranscoder directly. If you are trying to do something else,
> implementing your own ImageTranscoder and using
> PNGTranscode and JPEGTranscoder as sources of inspiration.
>
> May be Thierry, who wrote the transcoder framework, will have more
> comments.
>
> Cheers,
> Vincent.
>
> "Warren W. Thompson" wrote:
> >
> > I am attempting to render an SVG image file as a java.awt.Image, or one
> > of its subclasses like java.awt.image.BufferedImage. I have attempted to
> > directly render the SVG file and I have also attempted to transcode it.
> > I am currently using Batik version 1.1.
> >
> > I have achieved the most success with the following code snippet; however,
> > the BufferedImage that is returned is the correct shape without any colors
> > or details being drawn. I feel that I am missing some step in the rendering
> > process, and I have looked in detail at the Batik documentation and mailing
> > list archives to no avail.
> >
> > public static Image renderSVGDocument( URL url, int x, int y ){
> > // Create a rendereing context.
> > UserAgent userAgent = new UserAgentAdapter();
> > DocumentLoader loader = new DocumentLoader( userAgent );
> > Document doc = null;
> > try {
> > doc = loader.loadDocument( url.toString() );
> > } catch( Exception ex ){
> > ex.printStackTrace();
> > }
> > BridgeContext ctx = new BridgeContext(userAgent, loader);
> >
> > // Create a buffered image.
> > BufferedImage bufImg =
> > new BufferedImage( x, y, BufferedImage.TYPE_INT_ARGB );
> > Graphics2D graphics = GraphicsUtil.createGraphics( bufImg );
> >
> > // Create a builder and root node.
> > GVTBuilder builder = new GVTBuilder();
> > GraphicsNode root = null;
> >
> > // Render the SVG image.
> > try {
> > root = builder.build(ctx, doc);
> > root.paint(graphics);
> > } catch (Exception e) {
> > e.printStackTrace();
> > }
> >
> > return bufImg;
> > }
> >
> > Thanks in advance for your assistance!
> >
> > Warren W. Thompson
> >
> > Beer is proof that God loves us and wants us to be happy.
> > --Benjamin Franklin
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
> > For additional commands, e-mail: batik-users-help@xml.apache.org
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
> For additional commands, e-mail: batik-users-help@xml.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org
Re: Render SVG as a BufferedImage
Posted by Vincent Hardy <vi...@sun.com>.
Warren,
The org.apache.batik.transcoder.image.ImageTranscoder class should
be exactly what you want. If you are trying to convert images to
PNG or JPEG, you may even be able to use the PNGTranscoder or the
JPEGTranscoder directly. If you are trying to do something else,
implementing your own ImageTranscoder and using
PNGTranscode and JPEGTranscoder as sources of inspiration.
May be Thierry, who wrote the transcoder framework, will have more
comments.
Cheers,
Vincent.
"Warren W. Thompson" wrote:
>
> I am attempting to render an SVG image file as a java.awt.Image, or one
> of its subclasses like java.awt.image.BufferedImage. I have attempted to
> directly render the SVG file and I have also attempted to transcode it.
> I am currently using Batik version 1.1.
>
> I have achieved the most success with the following code snippet; however,
> the BufferedImage that is returned is the correct shape without any colors
> or details being drawn. I feel that I am missing some step in the rendering
> process, and I have looked in detail at the Batik documentation and mailing
> list archives to no avail.
>
> public static Image renderSVGDocument( URL url, int x, int y ){
> // Create a rendereing context.
> UserAgent userAgent = new UserAgentAdapter();
> DocumentLoader loader = new DocumentLoader( userAgent );
> Document doc = null;
> try {
> doc = loader.loadDocument( url.toString() );
> } catch( Exception ex ){
> ex.printStackTrace();
> }
> BridgeContext ctx = new BridgeContext(userAgent, loader);
>
> // Create a buffered image.
> BufferedImage bufImg =
> new BufferedImage( x, y, BufferedImage.TYPE_INT_ARGB );
> Graphics2D graphics = GraphicsUtil.createGraphics( bufImg );
>
> // Create a builder and root node.
> GVTBuilder builder = new GVTBuilder();
> GraphicsNode root = null;
>
> // Render the SVG image.
> try {
> root = builder.build(ctx, doc);
> root.paint(graphics);
> } catch (Exception e) {
> e.printStackTrace();
> }
>
> return bufImg;
> }
>
> Thanks in advance for your assistance!
>
> Warren W. Thompson
>
> Beer is proof that God loves us and wants us to be happy.
> --Benjamin Franklin
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
> For additional commands, e-mail: batik-users-help@xml.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org