Hi,
We tried improving the resolution of JFree image using the PNG Image encoder code posted on JFree. But canvas size is too big when I incrase the resolution to 300 dpi.
public BufferedImage getHiResChartImage(JFreeChart chart, double resolution, double width, double height, int imageType)
{
int screenResolution = Toolkit.getDefaultToolkit().getScreenResolution();
double scaleRatio = resolution / screenResolution;
int rasterWidth = (int) (width * scaleRatio);
int rasterHeight = (int) (height * scaleRatio);
log("rasterWidth : "+rasterWidth);
log("rasterHeight : "+rasterHeight);
log("scaleRatio : "+scaleRatio);
//BufferedImage image = new BufferedImage(rasterWidth, rasterHeight, BufferedImage.TYPE_INT_RGB);
BufferedImage image = chart.createBufferedImage((int)width,(int)height);
Graphics2D g2 = image.createGraphics();
g2.transform(AffineTransform.getScaleInstance(scaleRatio, scaleRatio));
chart.draw(g2, new Rectangle2D.Double(0, 0, width,height), null);
g2.dispose();
return image;
}
public String saveHiResImage(JFreeChart chart, double width, double height, double resolution, int imageType) {
String fileName = "JFreeImage_" + getUniqueTime();
String extension = ".png";
String file = "D:\\Vinayak\\RMD\\Chart_Evaluation\\images\\HiRes\\" + fileName + "_" + width + "x" + height + "x_Res-" + resolution + "dpi" + extension;
try
{
BufferedImage rendImage = getHiResChartImage(chart,resolution, width, height, imageType);
PNGMetadata png = new PNGMetadata();
int resX = (int)Math.ceil(resolution * 0.0254f);
png.pHYs_pixelsPerUnitXAxis = resX;
png.pHYs_pixelsPerUnitYAxis = resX;
png.pHYs_unitSpecifier = 1;
png.pHYs_present = true;
IIOImage iioImage = new IIOImage(rendImage, null, png);
//..Write generated image to a file
//.. Save as PNG
File f = new File(file);
ImageWriter writer = (ImageWriter) ImageIO.getImageWritersByFormatName("png").next();
ImageOutputStream ios = ImageIO.createImageOutputStream(f);
writer.setOutput(ios);
//.. Set the compression quality and other header information
ImageWriteParam iwparam = new ImageWriteParam()
{
public int getProgressiveMode()
{
return MODE_COPY_FROM_METADATA;
}
};
writer.write(png, iioImage, iwparam);
writer.write(iioImage);
writer.dispose();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return file;
}
If you comment the following line then size is proper but then again we do not get good resolution.
g2.transform(AffineTransform.getScaleInstance(scaleRatio, scaleRatio));
Please advise
PNG Image and Resize
Hi,
By "good resolution" you mean the resolution of the "file" the image is stored in? i.e.: the image file resolution?
I'll re-post my actual working code on this topic in a while...
I think you've missed a step that created a (very) big image (in memory) of the JFreeChart, and stores it in the file using the header to set the correct resolution... thus the ratio (resolution/image size - dpi) is correct in the file...
See the following post (in a while - since I don't have direct access to internet) and it should make sense !
Regards
By "good resolution" you mean the resolution of the "file" the image is stored in? i.e.: the image file resolution?
I'll re-post my actual working code on this topic in a while...
I think you've missed a step that created a (very) big image (in memory) of the JFreeChart, and stores it in the file using the header to set the correct resolution... thus the ratio (resolution/image size - dpi) is correct in the file...
See the following post (in a while - since I don't have direct access to internet) and it should make sense !
Regards
Tzaphkiel


Here is the code:
Like said in other parts of the forum, the screenResotion is the one of the machine running the code (have to get it using the toolkit) !
Hope this helps
Regards
Code: Select all
/**
* Method encodeAndWritePreviewImage.
*
* @param chart
* the JFreeChart instanciation to get the graphic from.
* @param filePath
* the wanted file path (including the file name and extension).
* @param _chartParams
* the name is explicit.
* @param overwrite
* if the files should be overwritten or left as is if they already
* exist.
* @return the fileName that was created
*/
public static final String encodeAndWritePreviewImage(Chart chart, String filePath, ChartParameter _chartParams,
boolean overwrite, boolean simpleFileNames)
{
File f = null;
ImageOutputStream ios = null;
// mm => cm
double width = _chartParams.getWidth(); //mm
double outputWidth = width / 10.0f; //cm
// mm => cm
double height = _chartParams.getHeight(); //mm
double outputHeight = height / 10.0f; //cm
float resolution = _chartParams.getResolution();//dpi
String fileName = filePath.substring(0, filePath.lastIndexOf("."));
String extension = filePath.substring(filePath.lastIndexOf(".") + 1);
String file;
DecimalFormat nf = new DecimalFormat("####");
if (!simpleFileNames)
file = fileName + "-" + nf.format(width) + "x" + nf.format(height) + "x" + nf.format(resolution) + "dpi." + extension;
else
file = fileName + "." + extension;
try
{
RenderedImage rendImage = chart.getHiResChartImage(resolution, outputWidth, outputHeight);
IIOImage iioImage = null;
if (extension.equals("png"))
{
PNGMetadata png = new PNGMetadata();
int resX = (int) Math.ceil(resolution / 0.0254f);
png.pHYs_pixelsPerUnitXAxis = resX;
png.pHYs_pixelsPerUnitYAxis = resX;
png.pHYs_unitSpecifier = 1;
png.pHYs_present = true;
iioImage = new IIOImage(rendImage, null, png);
}
else if (extension.equals("jpg"))
{
// DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
// DocumentBuilder parser = null;
// try
// {
// parser = fact.newDocumentBuilder();
// }
// catch (ParserConfigurationException e1)
// {
// e1.printStackTrace();
// }
// Document doc = parser.newDocument();
// Element dimensionElem = doc.createElement("Dimension");
// Element horizontalPixelSize =
// doc.createElement("HorizontalPixelSize");
// int resX = (int) Math.ceil(resolution / 0.0254f);
// horizontalPixelSize.setNodeValue("" + Math.round(1 / (resX * resX *
// 10)));
// dimensionElem.appendChild(horizontalPixelSize);
//
// Element verticalPixelSize = doc.createElement("VerticalPixelSize");
// verticalPixelSize.setNodeValue("" + Math.round(1 / (resX * resX *
// 10)));
// dimensionElem.appendChild(verticalPixelSize);
//
// jpegMetadata = new JPEGMetadata();
// jpegMetadata.mergeTree(IIOMetadataFormatImpl.standardMetadataFormatName,
// dimensionElem);
iioImage = new IIOImage(rendImage, null, null);
}
f = new File(file);
if (!(!overwrite && f.exists()))
{
ImageWriter writer = (ImageWriter) ImageIO.getImageWritersByFormatName(extension).next();
ios = ImageIO.createImageOutputStream(f);
ImageWriteParam jpegWriteParam = null;
if (extension.equals("jpg"))
{
jpegWriteParam = writer.getDefaultWriteParam();
jpegWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
jpegWriteParam.setProgressiveMode(ImageWriteParam.MODE_DISABLED);
jpegWriteParam.unsetCompression();
// jpegWriteParam.setCompressionQuality(1.0f);
// jpegWriteParam.setCompressionType(null);
}
writer.setOutput(ios);
if (extension.equals("jpg"))
writer.write(null, iioImage, jpegWriteParam);
else
writer.write(iioImage);
writer.dispose();
}
else
{
Logger.getLogger("be.nbb.batchpubgraph.jobsbatchprog").warning(
f.getAbsolutePath() + " already exists and overwrite mode not set (-o) !");
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (ios != null)
try
{
ios.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
return file;
}
/**
* Method getHiResChartImage.
*
* @param resolution
* @param width
* @param height
* @return
*/
public BufferedImage getHiResChartImage(double resolution, double width, double height)
{
width = width / CM_TO_INCH * _screenResolution;
height = height / CM_TO_INCH * _screenResolution;
double scaleRatio = resolution / _screenResolution;
int rasterWidth = (int) (width * scaleRatio);
int rasterHeight = (int) (height * scaleRatio);
BufferedImage image = new BufferedImage(rasterWidth, rasterHeight, BufferedImage.TYPE_INT_RGB);
// BufferedImage image = _chart.createBufferedImage(rasterWidth,
// rasterHeight, width, height, null);
Graphics2D g2 = image.createGraphics();
g2.transform(AffineTransform.getScaleInstance(scaleRatio, scaleRatio));
_chart.draw(g2, new Rectangle2D.Double(0, 0, width, height), null);
g2.dispose();
return image;
}
Hope this helps
Regards
Tzaphkiel

