Avg. Rating 3.4

Problem

I need to upload a rendered chart to a server-side Java application and save the result as a file.

Solution

The chart can be captured to a BitmapData object and converted to a byte array, which can then be read into a BufferedImage in Java and saved to a file. This example assumes you are already able to create and configure a remote Java object using Flex Data Services 2 and can use the ServiceLocator class from the Cairngorm framework.

Detailed explanation

We will need to export the data from Flex and pass it to a remote Java object. 

I'll run through the Flex code first.

import com.adobe.cairngorm.business.ServiceLocator;

public function exportBitmap():void {

//create a BitmapData object to hold the chart image
//change piechart1 to your chart name, or add a
//param to the method
var bd:BitmapData = new BitmapData(piechart1.width,
piechart1.allProjects.height);

//render the chart to the BitmapData
bd.draw(piechart1);

//Access the remote Java object (this is beyond the
//scope of this guide
var service:Object = ServiceLocator.getInstance()
.getRemoteObject("remoteObj");

//call the remote method which will accept the image
//data and save it
service.acceptImage(bd.getPixels(bd.rect),
bd.width, bd.height);

}

Note:  Using a remote object directly is a recommended design pattern, however this method is chosen to simply the code for this example.

Next we need to create the method in the Java object which will capture the data and store it to a compressed file on the server.

You will need the following imports:

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

Next paste the following method into your object.

public void acceptImage(byte[] bd, int width, int height) {

//create an BufferedImage
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);

//loop through all the pixels
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
//calculate array offset
int o = (x*4)+(y*width*4);

//set the pixel color
//here we will need to convert
//the byte data to an unsigned
//value using &0xFF before passing
//it to the Color constructor
image.setRGB(x, y, new Color(
bd[o+1]&0xFF, //red
bd[o+2]&0xFF, //green
bd[o+3]&0xFF //blue
).getRGB());
}
}

//write the image to a file
File file = new File("<your path here>");
try {ImageIO.write(image, "jpg", file);}
catch (IOException e) {e.printStackTrace();}
}

Make sure you've configured all the settings correctly in your code to access the remote Java object and fire up your server, then call the exportBitmap method from your Flex application and check for the exported image on the server.


You may wish to use a second hidden chart object of the correct size you wish the exported image to be, rather than incur scaling artifacts as people will undoubtably be uploading charts from different sized screens and windows.

This technique could also be applied to export images of other visual components or any BitmapData.

Note: The ImageSnapshot class in Livecycle Data Services supercedes the need for this technique.
Report abuse

Related recipes