I am trying to convert pages of a pdf to .pbm images. I am using following code for conversion:
for (int i=0; i<pages.size(); i++) {
PDPage singlePage = (PDPage) pages.get(i);
int pageno=i+1;
BufferedImage buffImage = null;
String imagefilename=prefix+"-"+pageno+".pbm";
try {
buffImage = singlePage.convertToImage();
} catch (IOException e1) {
System.out.println("Font not found");
return;
}
try {
File output=new File(imagefilename);
if (buffImage!=null){
ImageIO.write( buffImage, "pbm", output);
}
} catch (Exception e) {
System.out.println("File can not be written, check permission?");
}
}
When I am trying to write to png files, this seem to work perfectly, but I can not write to pbm files. ImageIO.write( buffImage, "pbm", output); returns false. What can be a possible remedy?
Related
I have an image and I do somethings with it, finally I get an BufferedImage object(the sub image of original image), now I want to save the sub image to FastDFS without save it in my local, what should I do?
I have already save sub image as file to my local, but I don't want to do like this, because it makes waste.
String oriPicPathInFastDFS = "http://127.0.0.1/xx/xx/xx/xx";
BufferedImage image = null;
try {
image = ImageIO.read(new URL(oriPicPathInFastDFS));
} catch (IOException e) {
e.printStackTrace();
}
// do something
// this is the sub image that I want to save to FastDFS
BufferedImage subImage = image.getSubimage(5, 5, 5, 5);
// these code can save the sub image to my local and then upload to fastDFS
String localPath = "/home/xx/x/xx.jpg";
File detectionFile = new File(localPath);
try {
detectionFile.createNewFile();
ImageIO.write(subImage, "jpg", detectionFile);
} catch (IOException e) {
e.printStackTrace();
}
// upload to fast dfs
I want to upload the subImage to fastDFS without save it to my local.
Fine, I got a method to solve this question.
// change the BufferedImage to byte[]
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
boolean flag = ImageIO.write(sunImage, "jpg", out);
} catch (IOException e) {
e.printStackTrace();
}
byte[] byteArray = out.toByteArray();
// then save the byteArray to fast DFS
I can check if byte array is a metafile image like wmf, emf using below java code
private boolean isMetaFileFormat(byte[] pictureData)
{
BufferedImage image = null;
try
{
image = ImageIO.read(new ByteArrayInputStream(pictureData));
if(image != null)
return false;
}
catch (Exception e){ }
return true;
}
but how to specifically check if it is emf or wmf image?
Thanks in advance...
WMF file's magic number is 0x9AC6CDD7, EMF magic number is 0x01000000.
Use Java Mime Magic Library for easy and common way. Download
MagicMatch match = Magic.getMagicMatch(your_byte_array);
String mimeType = match.getMimeType();
if(mimeType.equals("image/x-emf")) {
//here is emf
}
if(mimeType.equals("image/x-wmf")) {
//here is wmf
}
You can get image type from the byte array
byte[] pictureData = null;
ImageInputStream stream;
try {
stream = ImageIO.createImageInputStream(new ByteArrayInputStream(
pictureData));
Iterator<ImageReader> readers = ImageIO.getImageReaders(stream);
while (readers.hasNext()) {
ImageReader read = readers.next();
read.getFormatName();
}
} catch (Exception e) {
}
I am a beginner in java, and I am trying to write a simple screen-capture program. I wrote a simple SWING desktop app with a button and a text-field, and what I am trying to do is, when a user clicks that button the app takes a snapshot of the screen using awt.Robot, and sends that image and the text to a PHP script on my server.
My snapshot function so far is:
private void takeSnapShot(){
try {
Robot robot = new Robot();
Rectangle area = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage bufferedImage = robot.createScreenCapture(area);
//Try to save the captured image
try {
File file = new File("screenshot_full.png");
ImageIO.write(bufferedImage, "png", file);
} catch (IOException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (AWTException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
}
As you can see it's fairly simple so far, however I am not sure how to send that image to my PHP script without actually storing the image on user's PC.
Oh and I am using apache httpClient library for communicating to the web server. For the text I guess I can pass it in the URL as a get query, but I am not sure what to do about the image.
ImageIO.write can to an OutputStream of your choice.
So if you don't want to write the image to a File, you can simply write it to a different stream instead...
For example...
OutputStream os = null;
try {
Robot robot = new Robot();
Rectangle area = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage bufferedImage = robot.createScreenCapture(area);
//Try to save the captured image
try {
os = ...;
ImageIO.write(bufferedImage, "png", os);
} catch (IOException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
os.close();
} catch (Exception exp) {
}
}
} catch (AWTException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
Of course, I have no idea where you're sending the data, so you'll need to define the OutputStream yourself.
If you have the memory for it, you could write it a ByteArrayOutputStream and then write this to whatever output stream you need in the future...
To slightly modify your existing method, perhaps you could use a temporarily file and then delete it when you are finished with it. Perhaps it might look something like:
private void takeSnapShot(){
try {
Robot robot = new Robot();
Rectangle area = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage bufferedImage = robot.createScreenCapture(area);
//Try to save the captured image
try {
File file = File.createTempFile(Long.toString(System.currentTimeMillis()), ".png");
ImageIO.write(bufferedImage, "png", file);
//send image
file.delete();
} catch (IOException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (AWTException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
}
Another alternative would be to construct an int[][] from your BufferedImage which will hold the RGB values for every pixel of the image:
public int[][] getColors(final BufferedImage image){
assert image != null;
final int[][] colors = new int[image.getWidth()][image.getHeight()];
for(int x = 0; x < colors.length; x++)
for(int y = 0; y < colors[x].length; y++)
colors[x][x] = image.getRGB(x, y);
return colors;
}
I am a little unsure about what you hope to achieve; What do you plan on doing with the image?
Why don't you make this a WebsService and let your PHP consume it? You could send the binary data through the WebsService using some sort of Base64 encoder.
You could do this to get the bytes of the BufferedImage:
byte[] binaryData = ((DataBufferByte) bufferedImage.getData().getDataBuffer()).getData();
I am using below code to convert PDF to PNG image.
Document document = new Document();
try {
document.setFile(myProjectPath);
System.out.println("Parsed successfully...");
} catch (PDFException ex) {
System.out.println("Error parsing PDF document " + ex);
} catch (PDFSecurityException ex) {
System.out.println("Error encryption not supported " + ex);
} catch (FileNotFoundException ex) {
System.out.println("Error file not found " + ex);
} catch (IOException ex) {
System.out.println("Error handling PDF document " + ex);
}
// save page caputres to file.
float scale = 1.0f;
float rotation = 0f;
// Paint each pages content to an image and write the image to file
InputStream fis2 = null;
File file = null;
for (int i = 0; i < 1; i++) {
BufferedImage image = (BufferedImage) document.getPageImage(i,
GraphicsRenderingHints.SCREEN,
Page.BOUNDARY_CROPBOX, rotation, scale);
RenderedImage rendImage = image;
// capture the page image to file
try {
System.out.println("\t capturing page " + i);
file = new File(myProjectActualPath + "myImage.png");
ImageIO.write(rendImage, "png", file);
fis2 = new BufferedInputStream(new FileInputStream(myProjectActualPath + "myImage.png"));
} catch (IOException ioe) {
System.out.println("IOException :: " + ioe);
} catch (Exception e) {
System.out.println("Exception :: " + e);
}
image.flush();
}
myProjectPath is the path of the pdf file.
The problem is that I have pdf image of size 305 KB. When I use above code to convert image, the image size is 5.5 MB which is unexpected. Any reason why this is happening? Is there way to compress this? If I get solution to compress the size (by making down the pixel size), it is also OK.
Note : For other pdf files, images are coming to 305 KB. This is happening with one PDF file and not sure why this is happening.
Edit 1
I am using jar files as
icepdf-core.jar
icepdf-viewer.jar
The import that I have are
import org.icepdf.core.exceptions.PDFException;
import org.icepdf.core.exceptions.PDFSecurityException;
import org.icepdf.core.pobjects.Document;
import org.icepdf.core.pobjects.Page;
import org.icepdf.core.util.GraphicsRenderingHints;
You could extract the images from the pdf (example using PDFBox):
List<PDPage> pages = document.getDocumentCatalog().getAllPages();
for(PDPage page : pages) {
Map<String, PDXObjectImage> images = page.getResources().getImages();
for(PDXObjectImage image : images.values()){
//TODO: write image to disk
}
}
OR/AND you may want to save them as jpg to disk, as jpg overs compression as opposed to png.
You could even identify the format of the orignal image and use that when writing to disk by calling:
image.getSuffix();
You should be able to change the size of the file by changing scale. PDFs are often much smaller then rendered images. They can represent text and vector graphics which the rendered image will use a lot of bytes to represent. I'm actually somewhat surprised that any of your pngs are about the same size as the pdfs (unless the pdfs are just pictures).
I have created a graphical image with the following sample code.
BufferedImage bi = new BufferedImage(50,50,BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g2d = bi.createGraphics();
// Draw graphics.
g2d.dispose();
// BufferedImage now has my image I want.
At this point I have BufferedImage which I want to convert into an IMG Data URI. Is this possible? For example..
<IMG SRC="data:image/png;base64,[BufferedImage data here]"/>
Not tested, but something like this ought to do it:
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(bi, "PNG", out);
byte[] bytes = out.toByteArray();
String base64bytes = Base64.encode(bytes);
String src = "data:image/png;base64," + base64bytes;
There are lots of different base64 codec implementations for Java. I've had good results with MigBase64.
You could use this solution which doesn't use any external libraries. Short and clean! It uses a Java 6 library (DatatypeConverter). Worked for me!
ByteArrayOutputStream output = new ByteArrayOutputStream();
ImageIO.write(image, "png", output);
DatatypeConverter.printBase64Binary(output.toByteArray());
I use Webdriver, get captcha, like this below:
// formatName -> png
// pathname -> C:/Users/n/Desktop/tmp/test.png
public static String getScreenshot(WebDriver driver, String formatName, String pathname) {
try {
WebElement element = driver.findElement(By.xpath("//*[#id=\"imageCodeDisplayId\"]"));
File screenshot = element.getScreenshotAs(OutputType.FILE);
// base64 data
String base64Str = ImageUtil.getScreenshot(screenshot.toString());
return base64Str;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String getScreenshot(String imgFile) {
InputStream in;
byte[] data = null;
try {
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
String base64Str = new String(Base64.getEncoder().encode(data));
if (StringUtils.isAnyBlank(base64Str)) {
return null;
}
if (!base64Str.startsWith("data:image/")) {
base64Str = "data:image/jpeg;base64," + base64Str;
}
return base64Str;
}