Under Java what is the best way to go about converting an TIF file to a PNG?
Simplicity is preferable, but if the simplest way is to use a third party library then I would consider that solution.
First, install JAI. Then install JAI/ImageIO. Then do
public static void main(final String[] args) throws Exception
{
final BufferedImage tif = ImageIO.read(new File("test.tif"));
ImageIO.write(tif, "png", new File("test.png"));
}
Use imageMagic java libraries like im4java, their performance and quality is much better then JAI
for example:
import org.im4java.core.ConvertCmd;
import org.im4java.core.IMOperation;
public static void convertTifToPng(File inputImage, File outputImage){
IMOperation op = new IMOperation();
op.addImage(); //place holder for input file
op.addImage(); //place holder for output file
ConvertCmd convert = new ConvertCmd();
convert.run(op, new Object[]{inputImage.getAbsolutePath(), outputImage.getAbsolutePath()});
}
maven dependency for im4java is
<dependency>
<groupId>im4java</groupId>
<artifactId>im4java</artifactId>
<version>0.98.0</version>
</dependency>
Java advanced imaging APi is a good library for image manipulations
http://java.sun.com/products/java-media/jai/iio.html
Download JIMI Software Development Kit jimi1_0.zip and set JimiProClasses.zip to your classpath
http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-client-419417.html#7259-jimi_sdk-1.0-oth-JPR
JIMI is older java image library, but it is easy to use and there is no platform dependent code (no native executables, can use it like standard jar)
import java.awt.Image;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import com.sun.jimi.core.Jimi;
public class JIMIImageConverter {
public static byte[] convert(byte[] inBytes, String inMimeType, String outMimeType) throws Exception{
Image rawImage = Jimi.getImage(new ByteArrayInputStream(inBytes), inMimeType);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Jimi.putImage(outMimeType, rawImage, outputStream);
return outputStream.toByteArray();
}
}
where inMimeType and outMimeType are graphics formats mimetypes
maybe you can use this code, works for me
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import java.io.IOException;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.SeekableStream;
public class ImageConvert {
public static RenderedImage[] readMultiPageTiff(String fileName)throws IOException{
File file = new File(fileName);
SeekableStream seekableStream = new FileSeekableStream(file);
ImageDecoder decoder = ImageCodec.createImageDecoder("tiff", seekableStream, null);
int numPages = decoder.getNumPages();
RenderedImage image[]= new RenderedImage[numPages];
int count = 0;
for(int i=0;i<decoder.getNumPages();i++){
image[i] = decoder.decodeAsRenderedImage(i);
count++;
}
String newFolderName;
String s3 = fileName;
String [] temp = null;
temp = s3.split("\\.");
int j;
j = 0;
do{
newFolderName = temp[j];
String spoonFeeding = newFolderName;
File f = new File(spoonFeeding);
f.mkdirs();
j++;
}while (j<1);
for (int i = 0; i < count; i++) {
RenderedImage page = decoder.decodeAsRenderedImage(i);
File fileObj = new File(newFolderName+"/" + (i+1) + ".png");
System.out.println("Saving " + fileObj.getCanonicalPath());
ParameterBlock parBlock = new ParameterBlock();
parBlock.addSource(page);
parBlock.add(fileObj.toString());
parBlock.add("png");
RenderedOp renderedOp = JAI.create("filestore",parBlock);
renderedOp.dispose();
}
return image;
}
}
Related
Friends, I am using PDFBox 2.0.6. I have been successfull in extracting images from the pdf file, But right now it is creating an image for single pdf page. But the issue is that there can be any no. of images in a pdf page, And I want that each embedded image should be extracted as a single image itself.
Here is the code,
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
public class DemoPdf {
public static void main(String args[]) throws Exception {
//Loading an existing PDF document
File file = new File("C:/Users/ADMIN/Downloads/Vehicle_Photographs.pdf");
PDDocument document = PDDocument.load(file);
//Instantiating the PDFRenderer class
PDFRenderer renderer = new PDFRenderer(document);
File imageFolder = new File("C:/Users/ADMIN/Desktop/image");
for (int page = 0; page < document.getNumberOfPages(); ++page) {
//Rendering an image from the PDF document
BufferedImage image = renderer.renderImage(page);
//Writing the image to a file
ImageIO.write(image, "JPEG", new File(imageFolder+"/" + page +".jpg"));
System.out.println("Image created"+ page);
}
//Closing the document
document.close();
}
}
Is it possible in PDFBox that I can extract all embedded images as separate images, Thanks
Yes. It is possible to extract all images from all the pages in pdf.
You may refer this link, extract images from pdf using PDFBox.
The basic idea here is that, extend the class with PDFStreamEngine, and override processOperator method. Call PDFStreamEngine.processPage for all the pages. And if the object that has been passed to processOperator is an Image Object, get BufferedImage from the object, and save it.
Extend PDFStreamEngine and override the processOperator some thing like
#Override
protected void processOperator( Operator operator, List<COSBase> operands) throws IOException
{
String operation = operator.getName();
if( "Do".equals(operation) )
{
COSName objectName = (COSName) operands.get( 0 );
PDXObject xobject = getResources().getXObject( objectName );
if( xobject instanceof PDImageXObject)
{
PDImageXObject image = (PDImageXObject)xobject;
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
// same image to local
BufferedImage bImage = new BufferedImage(imageWidth,imageHeight,BufferedImage.TYPE_INT_ARGB);
bImage = image.getImage();
ImageIO.write(bImage,"PNG",new File("c:\\temp\\image_"+imageNumber+".png"));
imageNumber++;
}
else
{
}
}
else
{
super.processOperator( operator, operands);
}
}
This answer is similar with #jprism. But this is intended for someone who want just copy and paste this ready to use code with demo.
import org.apache.pdfbox.contentstream.PDFStreamEngine;
import org.apache.pdfbox.contentstream.operator.Operator;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
public class ExtractImagesUseCase extends PDFStreamEngine{
private final String filePath;
private final String outputDir;
// Constructor
public ExtractImagesUseCase(String filePath,
String outputDir){
this.filePath = filePath;
this.outputDir = outputDir;
}
// Execute
public void execute(){
try{
File file = new File(filePath);
PDDocument document = PDDocument.load(file);
for(PDPage page : document.getPages()){
processPage(page);
}
}catch(IOException e){
e.printStackTrace();
}
}
#Override
protected void processOperator(Operator operator, List<COSBase> operands) throws IOException{
String operation = operator.getName();
if("Do".equals(operation)){
COSName objectName = (COSName) operands.get(0);
PDXObject pdxObject = getResources().getXObject(objectName);
if(pdxObject instanceof PDImageXObject){
// Image
PDImageXObject image = (PDImageXObject) pdxObject;
BufferedImage bImage = image.getImage();
// File
String randomName = UUID.randomUUID().toString();
File outputFile = new File(outputDir,randomName + ".png");
// Write image to file
ImageIO.write(bImage, "PNG", outputFile);
}else if(pdxObject instanceof PDFormXObject){
PDFormXObject form = (PDFormXObject) pdxObject;
showForm(form);
}
}
else super.processOperator(operator, operands);
}
}
Demo
public class ExtractImageDemo{
public static void main(String[] args){
String filePath = "C:\\Users\\John\\Downloads\\Documents\\sample-file.pdf";
String outputDir = "C:\\Users\\John\\Downloads\\Documents\\Output";
ExtractImagesUseCase useCase = new ExtractImagesUseCase(
filePath,
outputDir
);
useCase.execute();
}
}
I am working with Apache POI. I am able to read data from excel, but unable to read image from the excel. How to read image from excel.
Instead of puzzling around let's have a complete example.
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.PictureData;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Iterator;
class ReadExcelImages {
public static void main(String[] args) throws Exception{
InputStream inp = new FileInputStream("test.xls");
//InputStream inp = new FileInputStream("test.xlsx");
Workbook workbook = WorkbookFactory.create(inp);
List lst = workbook.getAllPictures();
int i = 1;
for (Iterator it = lst.iterator(); it.hasNext(); ) {
PictureData pict = (PictureData)it.next();
String ext = pict.suggestFileExtension();
byte[] data = pict.getData();
if (ext.equals("png")){
FileOutputStream out = new FileOutputStream("pict" + i++ + ".png");
out.write(data);
out.close();
} else if (ext.equals("jpeg")) {
FileOutputStream out = new FileOutputStream("pict" + i++ + ".jpeg");
out.write(data);
out.close();
}
}
}
}
Works for me with HSSF (*.xls) as well as with XSSF (*.xlsx).
I am able to Read the input document using Apache POI and also able to find the data between the tags(What to be hidden) but the problem is i'm unable to write the data in the output file. How can i do the same to write the data and hide it in the output generated file..
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.hwpf.usermodel.CharacterRun;
import org.apache.poi.hwpf.usermodel.Range;
public class Hidden {
public static void main(String args[]) throws Exception
{
File file = new File("D://me1.doc");
FileInputStream fin = new FileInputStream(file);
FileOutputStream fout = new FileOutputStream("D://Test.doc");
HWPFDocument doc = new HWPFDocument(fin);
Range range = doc.getRange();
WordExtractor extractor = new WordExtractor(doc);
String para[] = extractor.getParagraphText();
String output="";
String hidden="";
for (String p : para) {
String[] w = p.split("[<\\>]");
for(int k=0 ;k<w.length;k++){
if(w[k]!=null && !"".equalsIgnoreCase(w[k])){
if("hidden".equalsIgnoreCase(w[k])){
k++;
CharacterRun run = range.getCharacterRun(k);
hidden= w[k];
k++;
System.out.println(hidden);
run.setVanished(true);
doc.write(fout);
}else{
}
}
}
}
fout.close();
fin.close();
}
}
I'd like to know, if there any way to replace images in ppt presentaions via Apache POI?
I have a template, where I've placed the elements (text fields and images) and I found out how to replace text, but didn't find anything for images.
Replacing images can be done in two ways:
Simply replace the image inside pptx-file, which is a zip file, under the path (/ppt/media). Checkout this post howto do it ..
or the POI method is to remove the file and add a new one ... and maybe change few other image properties (width, height, ...) - see below for an example
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import javax.xml.namespace.QName;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSheet;
import org.apache.xmlbeans.XmlCursor;
public class ReplaceImageInPptx {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("test2.pptx");
XMLSlideShow pptx = new XMLSlideShow(fis);
fis.close();
String blipNS[] = {
"http://schemas.openxmlformats.org/drawingml/2006/main",
"http://schemas.openxmlformats.org/presentationml/2006/main"
};
for (XSLFSheet slide : pptx.getSlides()) {
PackagePart packPart = slide.getPackagePart();
for (String ns : blipNS) {
XmlCursor picCur = slide.getXmlObject().newCursor();
picCur.selectPath("declare namespace p='"+ns+"' .//p:blip"); // or blipFill
while (picCur.toNextSelection()) {
// ... doesn't work for all namespaces ...
// CTBlipFillProperties blipFill = (CTBlipFillProperties)picCur.getObject();
// CTBlip blip = blipFill.getBlip();
// String relId = blip.getEmbed();
QName relName = new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "embed");
String relId = picCur.getAttributeText(relName);
// remove old media file and reference
PackageRelationship packRel = packPart.getRelationship(relId);
PackagePartName oldPartName = PackagingURIHelper.createPartName(packRel.getTargetURI());
packPart.getPackage().removePart(oldPartName);
// add something new
PackagePartName partName = PackagingURIHelper.createPartName("/ppt/media/smiley.jpg");
PackagePart part = pptx.getPackage().createPart(partName, "image/jpeg");
OutputStream partOs = part.getOutputStream();
FileInputStream fis2 = new FileInputStream("src/test/resources/smiley.jpg");
byte buf[] = new byte[1024];
for (int readBytes; (readBytes = fis2.read(buf)) != -1; partOs.write(buf, 0, readBytes));
fis2.close();
partOs.close();
PackageRelationship prs = slide.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
// blip.setEmbed(prs.getId());
picCur.setAttributeText(relName, prs.getId());
// maybe change the size a bit
// blipFill.getStretch().getFillRect().setL(<left padding in % (+/-)>)
}
picCur.dispose();
}
}
FileOutputStream fos = new FileOutputStream("test3.pptx");
pptx.write(fos);
fos.close();
}
}
I'm having a problem where I can't find images through Java. My friend and I are working on a project and we've done the exact same things. I've changed the paths to the location of the images and even dragged/dropped the images into Eclipse. However, I've had no luck. Here's my code:
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Toolkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MapArray {
static JPanel[][] tiles = new JPanel[30][29];
static String[][] images = new String[30][30];
final static int SIZE = 30;
static int place=0;
public MapArray(){
}
protected static ImageIcon createImageIcon(String path) {
java.net.URL imgURL = Map.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
public static void setMap(){
try {
String a = getFileContents("C:\\Users\\*****\\workspace\\Pokemon\\src\\map1.txt");
for(int x=0; x<29; x++){
for(int y=0; y<30; y++){
images[x][y]=a.substring(0,a.indexOf(" "));
a=a.substring(a.indexOf(" ")+1);
System.out.println(images[x][y]);
}
}
} catch (Exception e) {
System.out.println("y u no work :(");
}
}
public static String getFileContents(String fileName) throws Exception {
File theFile = new File(fileName);
byte[] bytes = new byte[(int) theFile.length()];
InputStream in = new FileInputStream(theFile);
int m = 0, n = 0;
while (m < bytes.length) {
n = in.read(bytes, m, bytes.length - m);
m += n;
}
in.close();
return new String(bytes);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
setMap();
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(30, 29, 0, 0));
for (int i = 0; i < 29; i++) {
for (int j = 0; j < 29; j++) {
tiles[i][j] = new JPanel(new GridLayout());
tiles[i][j].add(new JLabel(
createImageIcon("C:\\Users\\*****\\workspace\\Pokemon\\src\\tile"+"-"+images[i][j]+".png")));
frame.add(tiles[i][j]);
}
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
Everything I've tried with putting in the full image path doesn't work. Also, would anyone be able to help with relative paths? My friend and I will be sharing code between multiple computers so relative paths that aren't dedicated on where our workspace is located would be great. Thanks!
// get resource of *your* class, instead of Java's Map.class
MapArray.class.getResource(path);
...
String a = getFileContents("map1.txt"); // local path, not absolute
and put the file to your src folder, next to the MapArray.java file.
src/
|-- MapArray.java
|-- ...
`-- map1.txt
map1.txt will be moved into bin directory, next to .class file (bin/ is hidden in Eclipse by default, but that's where the classpath is set). Later you'll also want to make sure that the resource file is packaged into .jar.
would anyone be able to help with relative paths?
String a = getFileContents("./src/map1.txt");
Instead of posting a a whole bunch of code and not specifying the error message you get in your question, you could start with a simple code snippet (I neglect imports, ... since I am too lazy to fire up my IDE)
public static void main( String[] args ){
File file = new File( "C:...");//with the path you use in your code
System.out.println( file.exists() );
}
This is about what you need to discover/debug your problem. Then you can start on converting it to a relative path.
If the resources are inherently part of the app. (an embedded application resource) and not for write, they should be added to a Jar on the application's run-time class-path and accessed via URL obtained from Class.getResource(). It would work something like:
URL urlToMap1 = this.getClass().getResource("/src/map1.txt");
You'd need to check the exact path in the Jar that resource ends up at, and reference it from the root of the Jar (/) then the path within the Jar (src/map1.txt).