Convert WMF to PNG/BMP/JPG - java

How can I convert one WMF file to PNG/BMP/JPG format with custom output resolution?
Example: Take WMF file and outputs PNG file with 2000x2000 px.
Thanks in advance.

You can use the excelent Batik ( http://xmlgraphics.apache.org/batik/ ) lib to achieve this. But you will need to follow this steps:
Convert the WMF file to SVG using the WMFTranscoder
Convert the SVG to JGP using the JPGTranscoder
WMF >> SVG >> JPG
Here is a discussion on coderanch about it: http://www.coderanch.com/t/422868/java/java/converting-WMF-Windows-Meta-File

WMF, EMF and EMF+ are integral parts of slideshows, therefore I've developed a renderer for those as part of Apache POI. As for the upcoming POI-4.1.2 this is still work in progress - if you have any rendering issues, please upload your file in a new bug report in our bugzilla.
The main description can be found in the POI documentation.
Here is an excerpt:
#1 - Use PPTX2PNG via file or stdin
For file system access, you need to save your slideshow/WMF/EMF/EMF+ first to disc and then call PPTX2PNG.main() with the corresponding parameters.
for stdin access, you need to redirect System.in before:
/* the file content */
InputStream is = ...;
/* Save and set System.in */
InputStream oldIn = System.in;
try {
System.setIn(is);
String[] args = {
"-format", "png", // png,gif,jpg,svg or null for test
"-outdir", new File("out/").getCanonicalPath(),
"-outfile", "export.png",
"-fixside", "long",
"-scale", "800",
"-ignoreParse",
"stdin"
};
PPTX2PNG.main(args);
} finally {
System.setIn(oldIn);
}
#2 - Render WMF / EMF / EMF+ via the *Picture classes
File f = samples.getFile("santa.wmf");
try (FileInputStream fis = new FileInputStream(f)) {
// for WMF
HwmfPicture wmf = new HwmfPicture(fis);
// for EMF / EMF+
HemfPicture emf = new HemfPicture(fis);
Dimension dim = wmf.getSize();
int width = Units.pointsToPixel(dim.getWidth());
// keep aspect ratio for height
int height = Units.pointsToPixel(dim.getHeight());
double max = Math.max(width, height);
if (max > 1500) {
width *= 1500/max;
height *= 1500/max;
}
BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bufImg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
wmf.draw(g, new Rectangle2D.Double(0,0,width,height));
g.dispose();
ImageIO.write(bufImg, "PNG", new File("bla.png"));
}

You can use different tools for this format. You can choose for example GIMP. In Java you have a library for converting WMF files.

I wrote a walkaround here, for Java I learned that I can run shell command following answers in this question. For WMF, convert it to EMF first following this answer.

Related

Copying image and maintain orientation?

Edit
It turns out that the 2nd snippet is actually working but the images in question still show incorrectly in my IDE (IntelliJ IDEA) for some reason.
I am trying read an image, place a watermark and save it in a different folder and the below code does a good job, but it randomly orientates my images.
try {
final Image image = ImageIO.read(file);
int w = ((BufferedImage) image).getWidth();
int h = ((BufferedImage) image).getHeight();
final BufferedImage finalImage =
new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
//Graphics2D g = finalImage.createGraphics();
Graphics2D g = (Graphics2D) finalImage.getGraphics();
g.drawImage(image, 0, 0, null);
g.drawImage(watermark, 0, 0, null);
g.dispose();
File outputFile = new File("watermarked/" + folderName + "/" + file.getName());
outputFile.mkdirs();
ImageIO.write(finalImage, "jpg", outputFile);
} catch (IOException e) {
// TODO: notify client
e.printStackTrace();
}
After some reading I learned that ImageIO.read(...) does not maintain orientation or other "metadata" of the image it is processing. I also read about using the ImageReader to extract the metadata. According to the docs, using ImageReader.readall() should include the metadata in the returned IIOImage but I still end up with some of my images upside down. The below code demonstrates the copying without adding a watermark.
File out = new File("watermarked/" + folderName + "/" + file.getName());
out.getParentFile().mkdirs();
ImageInputStream input = ImageIO.createImageInputStream(file);
ImageOutputStream output = ImageIO.createImageOutputStream(out);
Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
ImageReader reader = readers.next();
reader.setInput(input);
IIOImage image = reader.readAll(0, null);
// Should not be needed since readAll should already take care of it.
IIOMetadata metadata = reader.getImageMetadata(0);
image.setMetadata(metadata);
ImageWriter writer = ImageIO.getImageWriter(reader);
writer.setOutput(output);
writer.write(image);
System.out.println(writer.canReplaceImageMetadata(0)); // Returns false
writer.replaceImageMetadata(0, metadata); // Results in a "Unsupported write variant" error.
Both code snippets reside in a method that get passed a folderName as a string and the actual image file.
Edit
The above snippet works and the issue is something else. In my windows folder all my images made with a Galaxy S8 show in the correct orientation. But when I copy them to my project and open them in IntelliJ IDEA some are oriented differently. So I added sanselan as a dependency to get more insight in the meta data of the images and the images that get a different orientation in the IDE do indeed show a different orientation in the metadata. But why aren't they oriented like that in the windows folder, am I missing a metadata field or is windows storing additional data somewhere outside the image metadata?

How to add an SVG to a PDF using iText7

I need to add an SVG graphic into PDF file.
Is it that possible using iText7?
Using iText5:
BufferedReader in = new BufferedReader(new InputStreamReader(svgUrl.openStream()));
String xmlParser = XMLResourceDescriptor.getXMLParserClassName();
SVGDocument svgDoc = new SAXSVGDocumentFactory(xmlParser).createSVGDocument(null, in);
in.close();
// Try to read embedded height and width
float svgWidth = Float.parseFloat(svgDoc.getDocumentElement().getAttribute("width").replaceAll("[^0-9.,]",""));
float svgHeight = Float.parseFloat(svgDoc.getDocumentElement().getAttribute("height").replaceAll("[^0-9.,]",""));
PdfTemplate svgTempl = PdfTemplate.createTemplate(writer, svgWidth, svgHeight);
Graphics2D g2d = svgTempl.createGraphics(svgWidth,svgHeight);
GraphicsNode chartGfx = (new GVTBuilder()).build(new BridgeContext(new UserAgentAdapter()), svgDoc);
chartGfx.paint(g2d);
g2d.dispose();
Image img = new ImgTemplate(svgTempl);
I found out that in the following page:
PdfPTable and PdfTemplate
there is a way to create something similar as Template:
PdfFormXObject svgTempl = new PdfFormXObject(new Rectangle(svgWidth, svgHeight));
How can I create Graphics2D?
Coincidentally, we're releasing our SVG implementation today. We don't support the full feature set just yet, we're still working on that in Q2 and beyond, but you can use it already. The artifact is on Maven. The repository is on Github. And the documentation is on our public wiki.
Code samples will be put on the web site, but it's a very simple API, similar to how pdfHtml works. There's an SvgConverter utility class that offers multiple ways to convert to PDF or PDF XObjects.
PdfDocument doc = new PdfDocument(
new PdfWriter(pdfOutputStream,
new WriterProperties().setCompressionLevel(0)));
doc.addNewPage();
SvgConverter.drawOnDocument(svg, doc, 1);
doc.close();
Source: I'm an iText developer working on the SVG implementation

pdf to .tiff conversion using java

I have created a web service that has a method which takes in a parameter of DataHandler. The purpose of this method is to read in what is sent over DataHandler and write it to a file(.tiff). When I pass in a .tiff file i can easily make a conversion but how should I make a conversion from a pdf file to a .tiff file using Java.
So if a user passes in a pdf file using DataHandler, how can I convert that to a .tiff file?
PDDocument doc = PDDocument.loadNonSeq(new File(filename), null);
boolean b;
List<PDPage> pages = doc.getDocumentCatalog().getAllPages();
for (int p = 0; p < pages.size(); ++p)
{
// RGB image with 300 dpi
BufferedImage bim = pages.get(p).convertToImage(BufferedImage.TYPE_INT_RGB, 300);
// alternatively: B/W image with 300 dpi
bim = pages.get(p).convertToImage(BufferedImage.TYPE_BYTE_BINARY, 300);
// save as TIF with dpi in the metadata
// PDFBox will choose the best compression for you
// you need to add jai_imageio to your classpath for this to work
b = ImageIOUtil.writeImage(bim, "page-" + (p+1) + ".tif", 300);
if (!b)
{
// error handling
}
}
If your question is about converting to a multipage TIFF, please say so, I have a solution for this too.

How to save a BufferedImage as a File

I am using the imgscalr Java library to resize an image .
The result of a resize() method call is a BufferedImage object. I now want to save this as a file (usually .jpg).
How can I do that? I want to go from BufferedImage -> File but perhaps this is not the correct approach?
File outputfile = new File("image.jpg");
ImageIO.write(bufferedImage, "jpg", outputfile);
The answer lies within the Java Documentation's Tutorial for Writing/Saving an Image.
The Image I/O class provides the following method for saving an image:
static boolean ImageIO.write(RenderedImage im, String formatName, File output) throws IOException
The tutorial explains that
The BufferedImage class implements the RenderedImage interface.
so it's able to be used in the method.
For example,
try {
BufferedImage bi = getMyImage(); // retrieve image
File outputfile = new File("saved.png");
ImageIO.write(bi, "png", outputfile);
} catch (IOException e) {
// handle exception
}
It's important to surround the write call with a try block because, as per the API, the method throws an IOException "if an error occurs during writing"
Also explained are the method's objective, parameters, returns, and throws, in more detail:
Writes an image using an arbitrary ImageWriter that supports the given format to a File. If there is already a File present, its contents are discarded.
Parameters:
im - a RenderedImage to be written.
formatName - a String containg the informal name of the format.
output - a File to be written to.
Returns:
false if no appropriate writer is found.
Throws:
IllegalArgumentException - if any parameter is null.
IOException - if an error occurs during writing.
However, formatName may still seem rather vague and ambiguous; the tutorial clears it up a bit:
The ImageIO.write method calls the code that implements PNG writing a “PNG writer plug-in”. The term plug-in is used since Image I/O is extensible and can support a wide range of formats.
But the following standard image format plugins : JPEG, PNG, GIF, BMP and WBMP are always be present.
For most applications it is sufficient to use one of these standard plugins. They have the advantage of being readily available.
There are, however, additional formats you can use:
The Image I/O class provides a way to plug in support for additional formats which can be used, and many such plug-ins exist. If you are interested in what file formats are available to load or save in your system, you may use the getReaderFormatNames and getWriterFormatNames methods of the ImageIO class. These methods return an array of strings listing all of the formats supported in this JRE.
String writerNames[] = ImageIO.getWriterFormatNames();
The returned array of names will include any additional plug-ins that are installed and any of these names may be used as a format name to select an image writer.
For a full and practical example, one can refer to Oracle's SaveImage.java example.
You can save a BufferedImage object using write method of the javax.imageio.ImageIO class. The signature of the method is like this:
public static boolean write(RenderedImage im, String formatName, File output) throws IOException
Here im is the RenderedImage to be written, formatName is the String containing the informal name of the format (e.g. png) and output is the file object to be written to. An example usage of the method for PNG file format is shown below:
ImageIO.write(image, "png", file);
Create and save a java.awt.image.bufferedImage to file:
import java.io.*;
import java.awt.image.*;
import javax.imageio.*;
public class Main{
public static void main(String args[]){
try{
BufferedImage img = new BufferedImage(
500, 500, BufferedImage.TYPE_INT_RGB );
File f = new File("MyFile.png");
int r = 5;
int g = 25;
int b = 255;
int col = (r << 16) | (g << 8) | b;
for(int x = 0; x < 500; x++){
for(int y = 20; y < 300; y++){
img.setRGB(x, y, col);
}
}
ImageIO.write(img, "PNG", f);
}
catch(Exception e){
e.printStackTrace();
}
}
}
Notes:
Creates a file called MyFile.png.
Image is 500 by 500 pixels.
Overwrites the existing file.
The color of the image is black with a blue stripe across the top.
Download and add imgscalr-lib-x.x.jar and imgscalr-lib-x.x-javadoc.jar to your Projects Libraries.
In your code:
import static org.imgscalr.Scalr.*;
public static BufferedImage resizeBufferedImage(BufferedImage image, Scalr.Method scalrMethod, Scalr.Mode scalrMode, int width, int height) {
BufferedImage bi = image;
bi = resize( image, scalrMethod, scalrMode, width, height);
return bi;
}
// Save image:
ImageIO.write(Scalr.resize(etotBImage, 150), "jpg", new File(myDir));
As a one liner:
ImageIO.write(Scalr.resize(ImageIO.read(...), 150));

Chinese characters converted to squares when using APACHE POI to convert PPT to Image

I got a problem when I try to use Apache POI project to convert my PPT to Images. My code as follows:
FileInputStream is = new FileInputStream("test.ppt");
SlideShow ppt = new SlideShow(is);
is.close();
Dimension pgsize = ppt.getPageSize();
Slide[] slide = ppt.getSlides();
for (int i = 0; i < slide.length; i++) {
BufferedImage img = new BufferedImage(pgsize.width, pgsize.height,
BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
//clear the drawing area
graphics.setPaint(Color.white);
graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
//render
slide[i].draw(graphics);
//save the output
FileOutputStream out = new FileOutputStream("slide-" + (i+1) + ".png");
javax.imageio.ImageIO.write(img, "png", out);
out.close();
It works fine except that all Chinese words are converted to some squares. Then how can I fix this?
This seems to be a bug with apache POI. I have added it in bugzilla
https://issues.apache.org/bugzilla/show_bug.cgi?id=54880
The problem is not on the POI side, but in the JVM font setting.
You need to set the font to one in the list of JVM fonts (/usr/lib/jvm/jdk1.8.0_20/jre/lib/fonts or similar), such as simsun.ttc.
XSLFTextShape[] phs = slide[i].getPlaceholders();
for (XSLFTextShape ts : phs) {
java.util.List<XSLFTextParagraph> tpl = ts.getTextParagraphs();
for(XSLFTextParagraph tp: tpl) {
java.util.List<XSLFTextRun> trs = tp.getTextRuns();
for(XSLFTextRun tr: trs) {
logger.info(tr.getFontFamily());
tr.setFontFamily("SimSun");
}
}
}
The issue is usage of FileOuputStream which will always write data to the file in default system encoding which is most probably ISO-8859_1 for Windows. Chinese characters are not supported by this encoding. You need to create a stream where you can write using UTF-8 encoding which needs creation of reader. I was looking at the API but did not find any methods taking reader as an argument. But check if ImageOutputStream can help you.

Categories

Resources