Hello Thomas,
On Mar 5, 2006, at 6:58 AM, [EMAIL PROTECTED] wrote:
Peter Wagener <[EMAIL PROTECTED]> wrote on 03/05/2006
12:37:24
AM:
I'm having trouble getting the initial embedded PNG to size itself
correctly when setting the original document on the JSVGCanvas. The
image is larger than the initial size of the canvas, but it doesn't
scale down correctly. Instead, I only see the upper-left corner
of it.
Interestingly enough, if I first set an SVG file as the document (I
created a blank SVG file in Illustrator), then append PNG's to that,
they are sized correctly. Apparently I'm not creating my initial
document correctly ... ?
The problem is that you aren't providing width/height/viewBox on
the outermost SVG element. I'm guessing your initial document
from Illustrator had those in it already.
Excellent -- adding the viewbox, height & width elements makes
everything work just fine. For future readers' sake, here's some
code that loads a PNG image from a file, create a blank SVG document,
then embed the PNG image into it:
<code>
// Load the PNG from the file
FileInputStream fileIn = new FileInputStream(inputFile);
PNGImageDecoder decoder = new PNGImageDecoder(fileIn, null);
RenderedImage image = decoder.decodeAsRenderedImage();
fileIn.close();
// Create the empty SVG document
DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
Document document = impl.createDocument(SVG_NS, "svg", null);
Element svgRoot = document.getDocumentElement();
// Set the initial attributes of the SVG Root element
int height = image.getHeight();
int width = image.getWidth();
svgRoot.setAttributeNS(null, "viewBox", "0 0 " + width +
" " + height);
svgRoot.setAttributeNS(null, "width", String.valueOf(width));
svgRoot.setAttributeNS(null, "height", String.valueOf(height));
// Create the PNG image element
Element imgElement = document.createElementNS(SVG_NS, "image");
imgElement.setAttributeNS(null, "width", String.valueOf(image.getWidth
()));
imgElement.setAttributeNS(null, "height", String.valueOf
(image.getHeight()));
// Encode the PNG into a base-64 string
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
Base64EncoderStream b64Encoder = new Base64EncoderStream(outStream);
ImageEncoder encoder = new PNGImageEncoder(b64Encoder, null);
try {
encoder.encode(image);
b64Encoder.close();
} catch (IOException e) {
e.printStackTrace();
}
// Set the b-64 data in the image element
imgElement.setAttributeNS(XLINK_NAMESPACE_URI, ATTR_XLINK_HREF,
DATA_PROTOCOL_PNG_PREFIX + outStream.toString());
svgRoot.appendChild(imgElement);
JSVGCanvas canvas = new JSVGCanvas();
canvas.setDocument(document);
</code>
Just a comment, it would be much better to have the build up
SVG file reference the PNG file as a separate file rather than
encoding the File as Base64 and embedding.
Because of the memory requirements to not have that PNG floating
around as a String? That makes sense. This app will eventually be
delivered with the images inside a JAR... how messy is it to
reference the PNG image as a URL inside a JAR file?
Also, I've noticed I'm not able to attach event listeners to image
elements in the same way I was with SVG elements. Is there a
difference in how those should be treated?
No. Event listeners should work just the same on an image element
as on anything else. Did you perhaps break having the document be
dynamic in the Canvas?
I'm not sure if I broke it or not... I don't think so :) What
confuses me is I have two very similar situations, except one is
using an <svg> node and the other is using an <image>. Sorry for the
lengthy description below, but I want to make sure I describe what
I'm seeing correctly.
In the first situation, I create an SVG document with an embedded PNG
image (as described above). I then load an SVG document, add an
event listener to the SVG's element, and append it to the document.
The event listener responds correctly. Here's the generated SVG file
(with internal elements & encoded PNG data stripped out):
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/
2001/REC-SVG-20010904/DTD/svg10.dtd'>
<svg contentScriptType="text/ecmascript"
width="599"
xmlns:xlink="http://www.w3.org/1999/xlink"
zoomAndPan="magnify"
contentStyleType="text/css"
height="773"
viewBox="0 0 599 773"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
xml:base=""
version="1.0">
<image width="599"
xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="data:image/png;base64,iVBORw0..."
xlink:type="simple"
xlink:actuate="onLoad"
height="773"
preserveAspectRatio="xMidYMid meet"
xlink:show="embed"/>
<svg contentScriptType="text/ecmascript"
zoomAndPan="magnify"
xmlns:xlink="http://www.w3.org/1999/xlink"
contentStyleType="text/css"
xmlns:x="http://ns.adobe.com/Extensibility/1.0/"
enable-background="new 0 0 35.162 463.158"
version="1.1" width="35.162"
xml:space="preserve"
xmlns:graph="http://ns.adobe.com/Graphs/1.0/"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 35.162 463.158"
height="463.158"
xmlns="http://www.w3.org/2000/svg"
xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/"
x="42"
overflow="visible"
y="200">
...
</svg>
</svg>
The second situation is very similar: I create the same SVG document
with the initial embedded PNG image. I then load another PNG as an
<image>, add an instance of the same event listener to the PNG's
element, then add that element to the document. The event listener
doesn't respond at all. Here's the generated SVG for that situation
(with the embedded PNG data stripped out):
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/
2001/REC-SVG-20010904/DTD/svg10.dtd'>
<svg contentScriptType="text/ecmascript"
width="599"
xmlns:xlink="http://www.w3.org/1999/xlink"
zoomAndPan="magnify"
contentStyleType="text/css"
height="773"
viewBox="0 0 599 773"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
xml:base=""
version="1.0">
<image width="599"
xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="data:image/png;base64,iVBORw0...."
xlink:type="simple"
xlink:actuate="onLoad"
height="773"
preserveAspectRatio="xMidYMid meet"
xlink:show="embed"/>
<image width="35"
xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="data:image/png;base64,iVBORw0KG...."
xlink:type="simple"
xlink:actuate="onLoad"
height="463"
preserveAspectRatio="xMidYMid meet"
xlink:show="embed" />
</svg>
Anything look wrong to you about situation #2? This seems to be my
last snag. Any other tips you can give would be greatly appreciated.
Thanks again,
Peter
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]