I am using iText and some SVG rendering library.
I want to render a SVG image to PDF. I am using following code to do that. Now the problem is I am giving an area chart SVG to it, it is not rendering line properly. Attaching screenshots.
Following classes has been used:
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.bridge.UserAgentAdapter;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.util.XMLResourceDescriptor;
import org.w3c.dom.svg.SVGDocument;
and here the cop snippet:
String parser = XMLResourceDescriptor.getXMLParserClassName();
factory = new SAXSVGDocumentFactory(parser);
UserAgent userAgent = new UserAgentAdapter();
DocumentLoader loader = new DocumentLoader(userAgent);
ctx = new BridgeContext(userAgent, loader);
ctx.setDynamicState(BridgeContext.DYNAMIC);
builder = new GVTBuilder();
PdfContentByte cb = writer.getDirectContent();
PdfTemplate chartImageTemplate = cb.createTemplate(1000, 1000);
SVGDocument svgDoc=null;
try {
InputStream in = new ByteArrayInputStream(chartImage.getBytes());
svgDoc = factory.createSVGDocument("", in);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try{
GraphicsNode mapGraphics = builder.build(ctx, svgDoc);
DefaultFontMapper mapper = new DefaultFontMapper();
PdfGraphics2D g2 = (PdfGraphics2D)cb.createGraphics(1000, 500, mapper);
Graphics2D g2d = g2;
mapGraphics.paint(g2d);
g2d.dispose();
cb.addTemplate(chartImageTemplate, 0, 0);
return mapGraphics.getGeometryBounds().getHeight();
}catch(Exception e){
}
You can find SVG here:
http://speedy.sh/xvDp8/demo.svg
Actual SVG:
Rendered PDF
Related
I want to create a PDF using image and some text. here image used as mask and text set on different spatial place.
I already generate pdf using image but cannot write text on it.
Here is the image
And output
My code
import com.itextpdf.text.*;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.FileOutputStream;
import javax.swing.JFileChooser;
public class Test {
public static void main(String[] args) {
Document document = new Document(PageSize.A4_LANDSCAPE, 0, 0, 0, 0);
String input = "src/icon/orginal_pad.jpg"; // .gif and .jpg are ok too!
JFileChooser fileChooser = new JFileChooser();
if (fileChooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
String filePath = fileChooser.getSelectedFile().getPath();
try {
FileOutputStream fos = new FileOutputStream(filePath);
PdfWriter writer = PdfWriter.getInstance(document, fos);
writer.open();
document.open();
Image im = Image.getInstance(input);
im.scaleToFit(PageSize.A4_LANDSCAPE.getWidth(), PageSize.A4_LANDSCAPE.getHeight());
document.add(im);
//code here
document.close();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
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
}
}
}
I have written a program (collecting from various sources, I am a beginner) in Java that takes a text(bengali) written in a .txt file and converts it to a .bmp image using the drawString function. The code is :
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
import java.util.*;
import java.awt.font.*;
import java.awt.geom.*;
class TextToImageDemo
{
public static void main(String[] args) throws IOException
{
String sampleText = "আমার",s="নাম";
BufferedReader br = null;
for (int u=1;u<=9;u++)
{
try
{
br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("E:\\Java\\bengtext\\f2-0"+u+".txt")),"UTF-8"));
while ((sampleText = br.readLine()) != null)
{
System.out.println(sampleText);
s=sampleText;
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (br != null)br.close();
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
//Image file name
String fileName = "Image";
//create a File Object
File newFile= new File("./" + fileName + ".jpeg");
//create the font you wish to use
Font font = new Font(/*Lohit Bengali*/"Kalpurush", Font.PLAIN, 50);
//create the FontRenderContext object which helps us to measure the text
FontRenderContext frc = new FontRenderContext(null, true, true);
//create a BufferedImage object
BufferedImage image = new BufferedImage(2000, 200, BufferedImage.TYPE_INT_RGB);
//calling createGraphics() to get the Graphics2D
Graphics2D g = image.createGraphics();
System.out.println(s);
//set color and other parameters
g.setColor(Color.WHITE);
g.fillRect(0, 0, 2000, 200);
g.setColor(Color.BLACK);
g.setFont(font);
FontMetrics fm=g.getFontMetrics();
Rectangle r=new Rectangle(fm.getStringBounds(s, g).getBounds());
String d=s.substring(1,s.length());
g.drawString(d, image.getWidth()/2-r.width/2, image.getHeight()/2+r.height/2);
//releasing resources
g.dispose();
try
{
FileOutputStream fos = new FileOutputStream("E:\\Java\\bengtext\\f2-0"+u+".bmp");
ImageIO.write(image,"bmp",fos);
fos.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
}
My main problem lies in the fact that a text like
দ্বিতীয়তা , একাগ্রতা , " জ্ঞান আহরনের একটি মাত্র উপায়
is formed like
How can this be solved?
Edit:
On checking all the 263 fonts available , I found only 6 of them were able to display bengali somewhat correctly. But in everyone of them the problem with the joint words lie as shown in the above picture. So question is : What is the exact problem happening here? Is JAVA not being able to read the joint words correctly, or is it not being able to draw them correctly ?
And secondly , how to make java draw the joint words correctly?
I'm using PDFBox 2. Trying to write a PNG image file to new PDF file.
I saw there was already an answer that mention it was fixed on PDFBox2:
How to add .png images to pdf using Apache PDFBox and
https://issues.apache.org/jira/browse/PDFBOX-1990
This is my code:
package pdfProj;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
public class b {
public static void main(String[] args) {
PDDocument doc = null;
doc = new PDDocument();
doc.addPage(new PDPage());
try{
BufferedImage awtImage = ImageIO.read( new File( "c://temp//line_chart.png" ) );
PDImageXObject pdImageXObject = LosslessFactory.createFromImage(doc, awtImage);
PDPageContentStream contentStream = new PDPageContentStream(doc, new PDPage(), true, false);
contentStream.drawImage(pdImageXObject, 200, 300, awtImage.getWidth() / 2, awtImage.getHeight() / 2);
contentStream.close();
doc.save( "c://temp//pdf//PDF_image.pdf" );
doc.close();
} catch (Exception io){
System.out.println(" -- fail --" + io);
}
}
}
There is no exception. Just getting an empty PDF file created.
The issue is that you add a new page to the document
doc.addPage(new PDPage());
but then create a content stream for yet another new page which you don't add to the document:
PDPageContentStream contentStream = new PDPageContentStream(doc, new PDPage(), true, false);
You should create the content stream for the page you added to the document, e.g. like this:
PDDocument doc = null;
doc = new PDDocument();
PDPage page = new PDPage();
doc.addPage(page);
try{
BufferedImage awtImage = ImageIO.read( new File( "c://temp//line_chart.png" ) );
PDImageXObject pdImageXObject = LosslessFactory.createFromImage(doc, awtImage);
PDPageContentStream contentStream = new PDPageContentStream(doc, page, true, false);
contentStream.drawImage(pdImageXObject, 200, 300, awtImage.getWidth() / 2, awtImage.getHeight() / 2);
contentStream.close();
doc.save( "c://temp//pdf//PDF_image.pdf" );
doc.close();
} catch (Exception io){
System.out.println(" -- fail --" + io);
}
I am trying to save a resized picture to the user's desktop but not sure how to do that.
Here's my code so far:
mi.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String userhome = System.getProperty("user.home");
fileChooser = new JFileChooser(userhome + "\\Desktop");
fileChooser.setAutoscrolls(true);
switch (fileChooser.showOpenDialog(f)) {
case JFileChooser.APPROVE_OPTION:
BufferedImage img = null;
try {
img = ImageIO.read(fileChooser.getSelectedFile());
} catch (IOException e1) {
e1.printStackTrace();
}
Image dimg = img.getScaledInstance(f.getWidth(),
f.getHeight(), Image.SCALE_SMOOTH);
path = new ImageIcon(dimg);
configProps.setProperty("Path", fileChooser
.getSelectedFile().getPath());
imBg.setIcon(path);
break;
}
}
});
The code above resizes the imaged selected to fit the size of the JFrame then sets it to the JLabel.
This all works well but I also want to output the file to a set location lets say to the users desktop to make it easier. I'm currently looking at output stream but can't quite get my head around it.
Any help would be great.
Get the current Icon from the JLabel...
Icon icon = imgBg.getIcon();
Paint the icon to a BufferedImage...
BufferedImage img = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
icon.paintIcon(null, g2d, 0, 0);
g2d.dispose();
Save the image to a file...
ImageIO.write(img, "png", new File("ResizedIcon.png"));
(and yes, you could use a JFileChooser to pick the file location/name)
You should also take a look at this for better examples of scaling an image, this way, you could scale the BufferedImage to another BufferedImage and save the hassle of having to re-paint the Icon
You might also like to take a look at Writing/Saving an Image
This is a example which is about saving images from Web to the local.
package cn.test.net;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class ImageRequest {
/**
* #param args
*/
public static void main(String[] args) throws Exception {
//a url from web
URL url = new URL("http://img.hexun.com/2011-06-21/130726386.jpg");
//open
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
//"GET"!
conn.setRequestMethod("GET");
//Timeout
conn.setConnectTimeout(5 * 1000);
//get data by InputStream
InputStream inStream = conn.getInputStream();
//to the binary , to save
byte[] data = readInputStream(inStream);
//a file to save the image
File imageFile = new File("BeautyGirl.jpg");
FileOutputStream outStream = new FileOutputStream(imageFile);
//write into it
outStream.write(data);
//close the Stream
outStream.close();
}
public static byte[] readInputStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
//every time read length,if -1 ,end
int len = 0;
//a Stream read from buffer
while( (len=inStream.read(buffer)) != -1 ){
//mid parameter for starting position
outStream.write(buffer, 0, len);
}
inStream.close();
//return data
return outStream.toByteArray();
}
}
Hope this is helpful to you!