Creating a jpeg from a JGoDocument

Hi,

I have an application and I want to create a jpeg from the current state of a JDoDocument displayed in a JGoView. Can you give me some help with this, please?

Try the JPEGView example class in the imager sample subdirectory.

OK, I tried that, and I can save a jpg file now, but the jpg shows no nodes even though the nodes are visible in the JGoView.

Here’s the code

[code]
/*

  • SaveJGoViewAsJpeg.java
  • Created on 21 June 2007, 01:37
    */

package au.com.rmt.common.diagram.published;

import java.io.;
import java.awt.
;
import java.awt.image.;
import com.sun.image.codec.jpeg.
;
import com.nwoods.jgo.*;

/**
*

  • @author RMT
    */
    public class SaveJGoViewAsJpeg extends JGoView {
    public SaveJGoViewAsJpeg(JGoDocument doc) {
    super(doc);
    }

    /**

    • Produce a JPEG file on the given OutputStream, showing a rendering

    • of this view’s document at a document location determined by

    • getViewPosition() at a scale determined by getScale() and of an

    • image size given by getViewSize() pixels.
      */
      public void render(OutputStream outs) {
      Dimension size = getViewSize();

      BufferedImage image = new BufferedImage(size.width, size.height,
      BufferedImage.TYPE_INT_RGB);

      Graphics2D g2 = image.createGraphics();

      // Get the rectangle that needs to be redrawn
      Rectangle clipRect = new Rectangle(0, 0, size.width, size.height);
      // Offset the clip rectangle according to the scroll and scale values
      convertViewToDoc(clipRect);

      g2.scale(getScale(), getScale());

      Point viewLoc = getViewPosition();
      g2.translate(-viewLoc.x, -viewLoc.y);

      paintView(g2, clipRect);

      try {
      JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outs);
      // The default JPEG quality is 75%. Increase it to 90%.
      JPEGEncodeParam param = (JPEGEncodeParam)encoder.getDefaultJPEGEncodeParam(image);
      param.setQuality((float)0.90, false);
      encoder.setJPEGEncodeParam(param);
      encoder.encode(image);
      } catch (Throwable t) {
      // Expected error if user reloads page before previous image finished.

       // System.out.println("Exception in JPEGView.render()");
       // System.err.println(t);
       // t.printStackTrace();
      

      }

      g2.dispose();
      }

    /**

    • The ViewSize property is maintained separately by this class because
    • we cannot depend on the Canvas actually being realized, and because
    • we want it to be independent of the Canvas.
      */
      public Dimension getViewSize() { return myViewSize; }

    public void setViewSize(Dimension d) {
    myViewSize.setSize(d);
    }

    // State
    private Dimension myViewSize = new Dimension(300, 240);
    }
    [/code]

I invoke with this line

new SaveJGoViewAsJpeg(_myJGoView.getDocument()).render(fos);

fos is a file output stream

FileOutputStream fos = new FileOutputStream(fileName);

woops … sorry, the jpeg is fine, it just was so small that it missed all of the nodes … please ignore the above message.

PS: I got it doing exactly what I need with absolutely no problems by adding a line to the constructor as follows

public class SaveJGoViewAsJpeg extends JGoView {
    public SaveJGoViewAsJpeg(JGoDocument doc) {
        super(doc);
        setViewSize(doc.getDocumentSize());
    }

Hi, I’m trying to do the same thing and tried to reuse your code straight-away.

In your code-snippet above,
Graphics2D g2 = image.createGraphics();

Graphics2D is java.awt.Graphics2D but

<font face="Courier New, Courier, mono">paintView(g2, clipRect);</font>

Expects a com.nwoods.jgo.Graphics2D. How did you make it work - wouldn’t even compile!!

Sharmaak, are you using SWT instead of AWT/Swing?

I'm not sure about how you can use com.sun.image.code.jpeg.* with SWT. I seem to remember reading about this issue on the web somewhere a long time ago, but I don't recall the details. Maybe there's another way in SWT, using a GC.

The JGo documentation for JGoView says this

<h3>paintView</h3><pre>protected void <b>paintView</b>(java.awt.Graphics2D g2,
                         java.awt.Rectangle clipRect)</pre>
<dl><dd>Render everything for this view that is within a given rectangle. The normal 
behavior fills in the paper color, draws any additional background, draws all of 
the document objects, and then draws any view objects. 
<p>This is infrequently overridden, except perhaps to change the default 
rendering hints. 
</p>
</dd><dd>


</dd><dd>
<dl><dt><b>Parameters:</b>
</dt><dd><code>g2</code> - the Graphics2D graphics context to draw on.
</dd><dd><code>clipRect</code> - the clipping rectangle in document 
coordinates</dd></dl></dd></dl>

Since the class is defined as shown below, all the public and protected methods from JGoView are available to the code that I wrote.

public class SaveJGoViewAsJpeg extends JGoView

Interesting… I’m using JGo 5.2 and the documentation shipped with it is:

protected void paintView(com.nwoods.jgo.Graphics2D g2, 
org.eclipse.swt.graphics.Rectangle clipRect)
And yes, I'm using SWT - that may be the reason for difference in API.

I guess I’ll have to learn a little bit of SWT to get my work done (I’m not an eclipse programmer, was hoping for a free ride). :)

Thanks anyway for help, you sample code turned out very helpful.

I’m using JGo 5.0; it must have changed …

Try Netbeans, it is what I am using for the software I am working with, it seems to be easier and faster than eclipse … maybe that is just because I am used to Netbeans and not so used to Eclipse. I am using Netbeans 5.5.1 by the way.