- Applying Rendering Hints
- Managing Memory
- Scheduling Tiles
- Reformatting an Image
- Extending the Border
- A Rendering Example
- A Closer Look at the PlanarImage Class
- Using the RenderedOp Class
- Working with Tiles
- A Tiled-Image Viewer
- Writing to Pixels
- Creating an Aggregate Image
- A JAI Image Browser
- The Renderable Layer
- Conclusion
Using the RenderedOp Class
The RenderedOp class represents a node in the rendered layer. Even though RenderedOp has two public constructors, you don't normally need to construct it directly. To obtain a RenderedOp object, you must execute the JAI.create() or JAI. createNS() method with an operator argument.
RenderedOp extends the PlanarImage class, so it inherits all the RenderedImage data and properties, which are generated by application of the operator. RenderedOp also overrides most of the PlanarImage methods. In addition, it holds the name of the operation and the parameters passed to execute the operation.
Note that the RenderedOp class is serializable, which means that it implements the Serializable interface and the internal state of a RenderedOp object can be saved. Serialization is necessary for performing the image-related operations over the network using RMI (Remote Method Invocation). As we'll see in Chapter 15, only Serializable objects can be transported across the network. In other words, an image can be sent from a server to a client (and vice versa) only if it is serializable. As you probably know already, the AWT Image and BufferedImage objects are not serializable. Neither is PlanarImage.
NOTE
The serialization feature was introduced in JDK 1.1 because it was required by many Java core APIs, such as RMI and JavaBeans. See Appendix B to learn more about serialization.
Constructing a Rendered Node
Although the RenderedOp class has two public constructors, you will typically use a JAI.createXXX() method to create a rendered node. Doing so will save you the trouble of writing and debugging several lines of code. In some instances, however, you may want to construct a RenderedOp object by explicitly using a RenderedOp constructor. There are two constructor types in the RenderedOp class:
public RenderedOp(OperationRegistry registry, java.lang.String opName, java.awt.image.renderable.ParameterBlock pb, java.awt.RenderingHints hints)
public RenderedOp(java.lang.String opName, java.awt.image.renderable.ParameterBlock pb, java.awt.RenderingHints hints)
OperationRegistry, in which an operation is registered
Operation name
ParameterBlock, which holds the parameters
RenderingHints
To construct a node, you need four parameters:
If the value of the OperationRegistry argument is null, the default value is assumed. If the value of the RenderingHints argument is null, no hints are associated with the node.
Rendering a Node
Because RenderedOp is a subclass of PlanarImage, you can directly pass the RenderedOp object to Graphics2D's drawRenderedImage() to render a node. When a node is rendered directly from the RenderedOp object, the node is said to be frozen. This means that the node parameters are not allowed to change.
To avoid freezing the node, call the following method to create an instance of PlanarImage and then pass that instance to the drawRenderedImage() method:
public PlanarImage createInstance()
It is extremely important that the node not be frozen when operations are performed dynamically in a rendering chain. A certain dynamic operation may change the sources, parameters, and rendering hints of a node. If a node is frozen, these changes cannot be made.
In addition to the case already mentioned (i.e., direct rendering with Rendered Op), a rendered node is frozen in the following cases:
When the RenderedImage methods of RenderedOp are called (see the section titled Rendered Images in Chapter 10 for the RenderedImage interface)
When the overridden PlanarImage methods, which include get and set methods for sources, are called
Even if a node is frozen, serialization can "unfreeze" it because the instance variables that hold the rendering information are transient and hence not saved. Upon deserialization of a RenderedOp object, its rendering attributes can be changed again.
The RenderedOp class saves the resulting image from rendering in an instance variable. You can obtain the image with the following method:
public PlanarImage getRendering()
You can use this method for repeated rendering of the resulting image. If the node is edited, however, this method does create a new rendering. In such cases you need to call the createInstance() method again.
Sources and Sinks
A rendered node can have zero or more sources and sinks. Both the sources and the sinks are held in a Vector object. You can retrieve, add, and remove sources and sinks using the following methods:
public int getNumSources()
public java.lang.Object getNodeSource(int index)
public void addNodeSource(Object source)
public void setNodeSource(Object source, int index)
public boolean removeSource(PlanarImage source)
public void setSources(java.util.List sourceList)
public boolean removeSource(PlanarImage source)
public java.util.Vector getSinks()
public void addSink(PlanarImage sink)
public boolean removeSink(PlanarImage sink)
Rendered-Node Attributes
A rendered node has several attributes that are set while a node is being created. As mentioned earlier, a node can be edited. To edit a node, you typically retrieve an attribute, apply a particular rule or condition, and if applicable, assign a new value to the attribute. The RenderedOp class has set and get methods to do these things:
public OperationRegistry getRegistry()
public void setRegistry(OperationRegistry registry)
public String getOperationName()
public void setOperationName(String opName)
public ParameterBlock getParameterBlock()
public void setParameterBlock(ParameterBlock pb)
public RenderingHints getRenderingHints()
public void setRenderingHints(RenderingHints hints)
These attributes can be image related as well as operation related. The operation-related attributes include operation registry, operation name, operation parameters, and rendering hints. The operation parameters can be part of a ParameterBlock object.
Editing a Node
You can set the node attributes to edit a node, provided the node is not frozen. You can use the get and set methods in the previous section to modify a node.
To edit the parameters of an operation, you must first retrieve the Parameter Block, then modify it and set it again. Alternatively, you can use the following RenderedOp methods to retrieve and set a desired parameter.
Get methods:
public int getNumParameters()
public java.util.Vector getParameters()
public byte getByteParameter(int index)
public char getCharParameter(int index)
public short getShortParameter(int index)
public int getIntParameter(int index)
public long getLongParameter(int index)
public float getFloatParameter(int index)
public double getDoubleParameter(int index)
public Object getObjectParameter(int index)
Set methods:
public void setParameter(byte param, int index)
There are similar methods for setting short, int, long, float, double, and object parameters.
Adding and Retrieving Properties
Some imaging operations may create image-related properties. The RenderedOp class has the following methods to help retrieve and set such properties:
public java.lang.String[] getPropertyNames()
public String getProperty(java.lang.String name)
public void setProperty(String name, Object value)
public void suppressProperty(String name)
public void addPropertyGenerator(PropertyGenerator pg)