Dynamically scale SVG image to the frame/window size - java

I am using SVGSalamander.
My code loads a svg image and sets it as background of a JDesktopPane.
File f = new File("awesome_tiger.svg");
SVGUniverse svgUniverse = new SVGUniverse();
try {
SVGDiagram diagram = svgUniverse.getDiagram(svgUniverse.loadSVG(f.toURL()));
try {
diagram.render(g);
}
catch(Exception ex) {System.out.println(ex);}}
catch (Exception ex2) {System.out.println(ex2);}
How can I achieve, that the image fills the window/frame completely and resizes with it?
Seems SVGSalamander has the method isScaleToFit() but how can I use it?
I use for antiAlias this: g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); (this is how it is written in the SVGIcon and SVGPanel classes)
Edit: solved it
AffineTransform at = new AffineTransform();
at.setToScale(jdpPane.getWidth()/diagram.getWidth(), jdpPane.getWidth()/diagram.getWidth());
g.transform(at);
diagram.render(g);
scales it proportionally

We can use an AffineTransform and the setToScale method
File f = new File("awesome_tiger.svg");
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
SVGUniverse svgUniverse = new SVGUniverse();
try {
SVGDiagram diagram = svgUniverse.getDiagram(svgUniverse.loadSVG(f.toURI().toURL()));
try {
AffineTransform at = new AffineTransform();
at.setToScale(jdpPane.getWidth()/diagram.getWidth(), jdpPane.getWidth()/diagram.getWidth());
g.transform(at);
diagram.render(g);
}
catch(Exception e2) {System.out.println(e2);}}
catch (Exception ex) {System.out.println(ex);}
this is the code with which I am overriding the paint() method

Related

save zoom image level to file

Let's say that I want to load an shp file, do my stuff on it and save the map as an image.
In order to save an image I am using:
public void saveImage(final MapContent map, final String file, final int imageWidth) {
GTRenderer renderer = new StreamingRenderer();
renderer.setMapContent(map);
Rectangle imageBounds = null;
ReferencedEnvelope mapBounds = null;
try {
mapBounds = map.getMaxBounds();
double heightToWidth = mapBounds.getSpan(1) / mapBounds.getSpan(0);
imageBounds = new Rectangle(0, 0, imageWidth, (int) Math.round(imageWidth * heightToWidth));
} catch (Exception e) {
// Failed to access map layers
throw new RuntimeException(e);
}
BufferedImage image = new BufferedImage(imageBounds.width, imageBounds.height, BufferedImage.TYPE_INT_RGB);
Graphics2D gr = image.createGraphics();
gr.setPaint(Color.WHITE);
gr.fill(imageBounds);
try {
renderer.paint(gr, imageBounds, mapBounds);
File fileToSave = new File(file);
ImageIO.write(image, "png", fileToSave);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
But, let's say I am doing something like this:
...
MapContent map = new MapContent();
map.setTitle("TEST");
map.addLayer(layer);
map.addLayer(shpLayer);
// zoom into the line
MapViewport viewport = new MapViewport(featureCollection.getBounds());
map.setViewport(viewport);
saveImage(map, "/tmp/img.png", 800);
1) The problem is that the zoom level isn't saved on the image file.Is there a way to save it?
2) When I am doing MapViewport(featureCollection.getBounds()); is there a way to extend a little bit the boundaries in order to have a better visual representation?
...
The reason that you aren't saving the map at the current zoom level is that in your saveImage method you have the line:
mapBounds = map.getMaxBounds();
which always uses the full extent of the map, you can change this to
mapBounds = map.getViewport().getBounds();
You can expand a bounding box by something like:
ReferencedEnvelope bounds = featureCollection.getBounds();
double delta = bounds.getWidth()/20.0; //5% on each side
bounds.expandBy(delta );
MapViewport viewport = new MapViewport(bounds);
map.setViewport(viewport );
A quicker (and easier) way to save a map from the GUI is to use a method like this which just saves exactly what is on the screen:
public void drawMapToImage(File outputFile, String outputType,
JMapPane mapPane) {
ImageOutputStream outputImageFile = null;
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(outputFile);
outputImageFile = ImageIO.createImageOutputStream(fileOutputStream);
RenderedImage bufferedImage = mapPane.getBaseImage();
ImageIO.write(bufferedImage, outputType, outputImageFile);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (outputImageFile != null) {
outputImageFile.flush();
outputImageFile.close();
fileOutputStream.flush();
fileOutputStream.close();
}
} catch (IOException e) {// don't care now
}
}
}

How to change Inset color in GRAL?

I'm trying to create GRAL graphs and export them as JPGs.
Not sure why, but the color of the 'Inset' areas (outside the border) seems to be defaulting to black. This is particularly confusing, as the docs seem to indicate that insets default to being white.
How can I change the color of the Inset?
Here is how I'm exporting the jpg
private void getJpg(BarPlot plot) {
BufferedImage bImage = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = (Graphics2D) bImage.getGraphics();
DrawingContext context = new DrawingContext(g2d);
plot.draw(context);
DrawableWriter wr = DrawableWriterFactory.getInstance().get("image/jpeg");
try {
wr.write(plot, new FileOutputStream("/path/out.jpg"), 800, 600);
} catch (IOException err) {
System.out.println(err);
}
}
Here is my current result (using white text on black bg for now, but want black text on white bg). current output
I figured it out! (with the help of a co-worker)
The Inset area defaults to being transparent black (RGBA(0,0,0,0)). Because of this, when the graph is exported as JPEG (which does not support transparency) it drops the alpha value and renders it all as black. By exporting as a png, I was able to preserve transparency and the graphs now look good when embedded into a document with a white background.
private static void getPng(XYPlot plot, String fileName) {
BufferedImage bImage = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) bImage.getGraphics();
DrawingContext context = new DrawingContext(g2d);
plot.draw(context);
DrawableWriter wr = DrawableWriterFactory.getInstance().get("image/png");
try {
wr.write(plot, new FileOutputStream(fileName + ".png"), 800, 600);
} catch (IOException err) {
System.out.println(err);
}
}

How can I display a chromatogram as an image?

I'm working with the 1.8.1 release of biojava on Netbeans, and using the ChromatogramGraphic Class to try to create an image of a chromatogram.
(http://www.biojava.org/docs/api1.8/)
I've made a file chooser to access chromatograms, and I use the ChromatogramFactory (from biojava) Class to create a Chromatogram Object from the file.
Apparently, this:
http://biojava.org/pipermail/biojava-l/2003-June/003896.html
code can accomplish what I want. I don't understand what it does, and I don't think I can use similar syntax to draw the image on my JFrame.
Any help would be greatly appreciated.
[What I have so far. I don't know what most of it does.]
private void renderTrace() throws IOException, UnsupportedChromatogramFormatException {
ABIFChromatogram abiChrom = new ABIFChromatogram();
File abi = new File(textarea.getText());
ABITrace abiTrace = new ABITrace(abi);
ABIFParser abiParse = new ABIFParser(abi);
ChromatogramFactory chromFactory = new ChromatogramFactory();
Chromatogram chrom = ChromatogramFactory.create(abi);
ChromatogramGraphic gfx = new ChromatogramGraphic(chrom);
gfx.setHeight(240);
gfx.setHorizontalScale(2.0f);
// set some options that affect the output
// turn off filled-in "callboxes"
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_A,
Boolean.FALSE);
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_C,
Boolean.FALSE);
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_G,
Boolean.FALSE);
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_T,
Boolean.FALSE);
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_OTHER,
Boolean.FALSE);
// this option controls whether each trace/callbox/etc is scaled/positioned
// individually, or whether the scaling is done on all shapes at the level
// of the graphics context
// enabling this option is recommended for higher-quality output
gfx.setOption(ChromatogramGraphic.Option.USE_PER_SHAPE_TRANSFORM,
Boolean.TRUE);
BufferedImage bi = new BufferedImage(
gfx.getWidth(),
gfx.getHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = bi.createGraphics();
g2.setBackground(Color.white);
g2.clearRect(0, 0, bi.getWidth(), bi.getHeight());
if (g2.getClip() == null) {
g2.setClip(new Rectangle(0, 0, bi.getWidth(), bi.getHeight()));
}
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// the main event
gfx.drawTo(g2);
// work-around an OS X bug where sometimes the last Shape drawn
// doesn't show up in the output
g2.draw(new java.awt.Rectangle(-10, -10, 5, 5));
gfx.drawTo();
}
If this works then you can draw the image using the paint() method of JFrame. First you need to make sure that this
gfx.drawTo(g2);
works, from the gfx side. Try to save the image into a file and see if its there
try {
ImageIO.write(bi, "png", new File("gfx-image.png"));
} catch (IOException ex) { ex.printStackTrace(); }
with import javax.imageio.*; in your import statements.
If that works and you can see the image then at the JFrame you need to have something like
public void paint(Graphics g) {
g.drawImage(bi, 0, 0, this);
}

iText makes color image appears black and white

I am using Graphics2D itext feature and draw image with g2.drawImage(x, y, null). If i load this image using ImageIO.read() image looks black and white in generated PDF. But Toolkit.getDefaultToolkit().createImage() works fine. Here is the code:
public static final String filename = "dummy.pdf";
public static void main(String[] args) {
try {
Document doc = new Document();
PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(filename));
writer.setPdfVersion(PdfWriter.VERSION_1_5);
doc.open();
PdfContentByte cb = writer.getDirectContent();
Graphics2D g2 = cb.createGraphics(1654, 1168);
draw(g2);
doc.close();
System.out.println("Done!");
} catch(Exception e) {
e.printStackTrace();
}
}
private static void draw(Graphics2D g2) throws Exception {
g2.setColor(Color.red);
g2.fill(new Rectangle2D.Double(0, 0, 100, 100));
BufferedImage img = ImageIO.read(new File("Speedy2BigClr.gif"));
BufferedImage bi = toBufferedImage(img);
Image i = makeColorTransparentAndBW(bi, Color.WHITE);
Image iii = Toolkit.getDefaultToolkit().createImage("Speedy2BigClr.gif");
g2.translate(0, 300);
g2.scale(0.3, 0.3);
g2.drawImage(img, 0, 0, null);
}
}
Unfortunately for another gif the ImageIO works fine, and Toolkit does not work. But all images look fine on screen. Why the way i load image affects the result in PDF?
P.S. For the clear reasons i am using LGPL iText (2.0.4, 2.1.7, 4.2.0).
UPD: works fine on iText-5.3.5, that i can not use :-(

Sending Screen Image and Showing continuously

I am making a project for Controlling a PC from any other PC on a Network.
but when i send the image from server to client, it does not changed, just the first image is displayed.
So i am sending the captured images of server to client using GZIP compression.
Here is the Server's Code:
out = new DataOutputStream(s.getOutputStream());
zipout = new GZIPOutputStream(out);
while(true)
{
img = conn.getScreenImg(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
//Here conn is a Object of Robot Class
ImageIO.write(img, "jpeg", zipout);
Thread.sleep(200);
System.out.println("Success");
}
Client Code: displaying the Images sent by Server.
while(true)
{
try
{
img = ImageIO.read(zipin);
Graphics g = this.getGraphics();
g.drawImage(img, 0, 0, this);
Thread.sleep(100);
}
catch (Exception e)
{
e.printStackTrace();
}
}
I need Help with this. The image doesn't change on client.
and i want to know that if it is good to use GZIP here for compression for images to send over network , will it accelerate the process. or should i use some other method.
The way you are displaying the images on the client doesn't seem right to me. It would be a lot better to write a custom JPanel that would override the paintComponent method and that would handle the image rendering. Something like below:
class ImagePanel extends JPanel {
private BufferedImage image = null;
private void setImage(BufferedImage img) {
image = img;
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if (image != null) {
g2.drawImage(image, 0, 0, null);
}
}
}
Inside your while loop you would call the setImage method on the panel. The panel in of course previously instantiated and added to a container.

Categories