I've got a problem. I use image, which takes big space e.g. 40000x40000 px.
and so there is a problem with the amount of memory. I've found a
compromise. The bigger cache we use the faster the performance will be.
I use my own ImageRenderer (DRenderer.java)
and RenderedImage (ExtRenderedImage.java) instead BufferedImage.
I suggest to use a RenderedImage in follow classes for flexibility.
org.apache.batik.bridge.RepaintManager;
org.apache.batik.bridge.UpdateManagerEvent;
org.apache.batik.swing.gvt.GVTTreeRenderer;
org.apache.batik.swing.gvt.GVTTreeRendererEvent;
org.apache.batik.swing.gvt.JGVTComponent;
org.apache.batik.swing.svg.JSVGComponent;
----------------------DRenderer---------------------------------
package org.apache.batik.gvt.renderer;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.awt.image.renderable.*;
import java.util.*;
import java.util.List;
import borlas.utils.*;
import borlas.utils.TileCache;
import org.apache.batik.ext.awt.geom.*;
import org.apache.batik.ext.awt.image.*;
import org.apache.batik.ext.awt.image.renderable.*;
import org.apache.batik.ext.awt.image.rendered.*;
import org.apache.batik.gvt.*;
import org.apache.batik.gvt.filter.*;
public class DRenderer implements ImageRenderer{
final static int COPY_OVERHEAD = 1000;
final static int COPY_LINE_OVERHEAD = 10;
protected RenderingHints renderingHints;
protected AffineTransform usr2dev;
protected GraphicsNode rootGN;
protected Filter rootFilter;
protected RenderedImage image = null;
protected int offScreenWidth;
protected int offScreenHeight;
protected boolean isDoubleBuffered;
protected RectListManager dirtyAreas = new RectListManager();
protected TileCache cache;
protected static RenderingHints defaultRenderingHints;
static {
defaultRenderingHints = new RenderingHints(null);
defaultRenderingHints.put(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
defaultRenderingHints.put(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
}
public void setDoubleBuffered(boolean flag){
isDoubleBuffered = flag;
}
public boolean isDoubleBuffered(){
return isDoubleBuffered;
}
public AffineTransform getTransform(){
return usr2dev;
}
public void setTransform(AffineTransform usr2dev){
if (this.usr2dev.equals(usr2dev))
return;
if(usr2dev == null) this.usr2dev = new AffineTransform();
else this.usr2dev = new AffineTransform(usr2dev);
}
public void updateOffScreen(int width, int height) {
offScreenWidth = width;
offScreenHeight = height;
}
public void dispose() {
rootGN = null;
rootFilter = null;
renderingHints = null;
}
public void repaint(Shape area){
if (area == null) return;
List l = new ArrayList(1);
l.add(area);
repaint(l);
}
public GraphicsNode getTree(){
return rootGN;
}
public void setTree(GraphicsNode rootGN){
this.rootGN = rootGN;
rootFilter = null;
image = null;
renderingHints = new RenderingHints(defaultRenderingHints);
}
public DRenderer(TileCache tci){
cache = tci;
renderingHints = new RenderingHints(defaultRenderingHints);
usr2dev = new AffineTransform();
}
public DRenderer(RenderingHints rh,
AffineTransform at,TileCache tci){
cache = tci;
renderingHints = new RenderingHints(rh);
usr2dev = new AffineTransform(at);
}
public void flush(){
cache.flush();
}
public void clearOffScreen() {
renderGNR();
}
public void repaint(RectListManager rLM){
Iterator iter = rLM.iterator();
while (iter.hasNext()) {
Rectangle r = (Rectangle)iter.next();
dirtyAreas.add(r);
}
dirtyAreas.mergeRects(COPY_OVERHEAD, COPY_LINE_OVERHEAD);
iter = dirtyAreas.iterator();
while(iter.hasNext()){
Rectangle rect = (Rectangle)iter.next();
flush(rect);
}
dirtyAreas.clear();
return;
}
public void flush(Rectangle r) {
if(image == null) return;
r = usr2dev.createTransformedShape(r).getBounds();
int lb = xToTile(r.x);
int rb = xToTile(r.x + r.width);
int tb = yToTile(r.y);
int bb = yToTile(r.y + r.height);
for(int i = lb; i <= rb; i++){
for(int j = tb; j <= bb; j++){
cache.removeTile(image,i,j);
}
}
return;
}
public void flush(Collection areas) {
Iterator iter = areas.iterator();
while(iter.hasNext()){
Rectangle rect = ((Shape)iter.next()).getBounds();
dirtyAreas.add(rect);
}
dirtyAreas.mergeRects(COPY_OVERHEAD, COPY_LINE_OVERHEAD);
iter = dirtyAreas.iterator();
while(iter.hasNext()){
Rectangle rect = (Rectangle)iter.next();
flush(rect);
}
dirtyAreas.clear();
return;
}
public RenderedImage getOffScreen() {
if (rootGN == null) return null;
return image;
}
public void repaint(List areas) {
if (areas == null) return;
if(image == null ||
image.getWidth() < offScreenWidth
|| image.getHeight() < offScreenHeight
){
renderGNR();
}
flush(areas);
}
protected int xToTile(int x){
int off = image.getTileGridXOffset();
int tw = image.getTileWidth();
return (x - off)/tw;
}
protected int yToTile(int y){
int off = image.getTileGridYOffset();
int th = image.getTileHeight();
return (y - off)/th;
}
protected int xTileToX(int xt){
int off = image.getTileGridXOffset();
int tw = image.getTileWidth();
return xt*tw + off;
}
protected int yTileToY(int yt){
int off = image.getTileGridYOffset();
int th = image.getTileHeight();
return yt*th + off;
}
protected void renderGNR() {
if(rootGN == null) return;
if (rootFilter == null) {
rootFilter = rootGN.getGraphicsNodeRable(true);
}
cache.flush();
AffineTransform at, rcAT;
at = usr2dev;
rcAT = new AffineTransform(at.getScaleX(), at.getShearY(),
at.getShearX(),
at.getScaleY(),
0, 0);
RenderContext rc = new RenderContext(rcAT, null, renderingHints);
Rectangle bounds = new Rectangle(offScreenWidth,offScreenHeight);
RenderedImage ri = new
ExtRenderedImage((GraphicsNodeRable8Bit)rootFilter,rc.getTransform(),rc.getRenderingHints(),bounds);
if (ri == null){
image = null;
return;
}
CachableRed ret;
ret = GraphicsUtil.wrap(ri);
int dx = Math.round((float)at.getTranslateX());
int dy = Math.round((float)at.getTranslateY());
ret = new TranslateRed(ret, ret.getMinX()+dx, ret.getMinY()+dy);
image = GraphicsUtil.convertTosRGB(ret);
}
}
--------------------------------------------------------ExtRnderedImge---------------------------
package borlas.utils;
import org.apache.batik.ext.awt.image.GraphicsUtil;
import org.apache.batik.ext.awt.image.rendered.AbstractTiledRed;
import org.apache.batik.ext.awt.image.rendered.AbstractRed;
import org.apache.batik.ext.awt.image.rendered.CachableRed;
import java.awt.AlphaComposite;
import java.awt.Rectangle;
import java.awt.Point;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.filter.GraphicsNodeRable8Bit;
public class ExtRenderedImage extends AbstractRed {
private AffineTransform node2dev = null;
private GraphicsNodeRable8Bit filter = null;
private RenderingHints renderingHints = null;
public ExtRenderedImage(GraphicsNodeRable8Bit rable,
AffineTransform
node2dev,RenderingHints rh,
Rectangle bounds){
super(); // We _must_ call init...
filter = rable;
renderingHints = rh;
this.node2dev = node2dev;
ColorModel cm = GraphicsUtil.sRGB_Unpre;
int defSz = AbstractTiledRed.getDefaultTileSize();
// Make tile(0,0) fall on the closest intersection of defaultSz.
int tgX = defSz*(int)Math.floor(bounds.x/defSz);
int tgY = defSz*(int)Math.floor(bounds.y/defSz);
int tw = (bounds.x+bounds.width)-tgX;
if (tw > defSz) tw = defSz;
int th = (bounds.y+bounds.height)-tgY;
if (th > defSz) th = defSz;
if ((tw <= 0) || (th <= 0)) {
tw = 1;
th = 1;
}
// fix my sample model so it makes sense given my size.
SampleModel sm = cm.createCompatibleSampleModel(tw, th);
// Finish initializing our base class...
init((CachableRed)null, bounds, cm, sm, tgX, tgY, null);
}
public WritableRaster copyData(WritableRaster wr) {
genRect(wr);
return wr;
}
public void genRect(WritableRaster wr) {
// System.out.println(" Rect: " + wr.getBounds());
BufferedImage offScreen
= new BufferedImage(cm,
wr.createWritableTranslatedChild(0,0),
cm.isAlphaPremultiplied(),
null);
Graphics2D g = GraphicsUtil.createGraphics(offScreen,renderingHints);
g.setComposite(AlphaComposite.Clear);
g.fillRect(0, 0, wr.getWidth(), wr.getHeight());
g.setComposite(AlphaComposite.SrcOver);
g.translate(-wr.getMinX(), -wr.getMinY());
// Set transform
g.transform(node2dev);
filter.paintRable(g);
g.dispose();
}
}
---------------------------------------------------------------------------------------------------
And piece of MyCanvas that extends JSVGComponent
protected ImageRenderer createImageRenderer() {
if(isDynamicDocument){
return new DRenderer(cache);
}else{
return rendererFactory.createStaticImageRenderer();
}
}
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
Rectangle d = g.getClipBounds();
Dimension dim = this.getSize();
if(d == null){
d = new Rectangle(0,0,dim.width,dim.height);
}
g2d.setComposite(AlphaComposite.SrcOver);
g2d.setPaint(getBackground());
g2d.fillRect(0, 0, dim.width, dim.height);
paintPrev(g2d);
this.PaintBackground(g);
if (image != null) {
if (paintingTransform != null) {
g2d.transform(paintingTransform);
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int lb, rb, tb, bb;
int numTX = image.getNumXTiles();
int numTY = image.getNumYTiles();
int mtx = image.getMinTileX();
int mty = image.getMinTileY();
lb = xToTile(d.x);
lb = Math.max(lb, image.getMinTileX());
lb = Math.min(lb, mtx + numTX - 1);
rb = xToTile(d.x + d.width - 1);
rb = Math.max(rb, image.getMinTileX());
rb = Math.min(rb, mtx + numTX - 1);
tb = yToTile(d.y);
tb = Math.max(tb, image.getMinTileY());
tb = Math.min(tb, mty + numTY - 1);
bb = yToTile(d.y + d.height - 1);
bb = Math.max(bb, image.getMinTileY());
bb = Math.min(bb, mty + numTY - 1);
for(int i = lb; i <= rb; i++){
for(int j = tb; j <= bb; j++){
int tx = xTileToX(i);
int ty = yTileToY(j);
Raster raster = cache.getTile(image,i,j);
if(raster == null){
raster = image.getTile(i,j);
if(raster == null) return;
cache.addTile(image,i,j,raster);
}
DataBuffer dataBuffer = raster.getDataBuffer();
SampleModel sampleModel =
image.getSampleModel();
WritableRaster wr =
Raster.createWritableRaster(sampleModel,dataBuffer,new Point(0,0));
BufferedImage bi = new
BufferedImage(image.getColorModel(),wr,
image.getColorModel().isAlphaPremultiplied(),null);
g2d.drawRenderedImage(bi,
AffineTransform.getTranslateInstance(tx,ty));
}
}
Iterator it = overlays.iterator();
while (it.hasNext()) {
((Overlay)it.next()).paint(g);
}
}
}
protected int xToTile(int x){
int off = image.getTileGridXOffset();
int tw = image.getTileWidth();
return (x - off)/tw;
}
protected int yToTile(int y){
int off = image.getTileGridYOffset();
int th = image.getTileHeight();
return (y - off)/th;
}
protected int xTileToX(int xt){
int off = image.getTileGridXOffset();
int tw = image.getTileWidth();
return xt*tw + off;
}
protected int yTileToY(int yt){
int off = image.getTileGridYOffset();
int th = image.getTileHeight();
return yt*th + off;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]