I'm am trying to get the Icon from a .lnk file, put it into a javafx Image and then save it as a .png file (to ensure it's working).
My current code compiles but does not work:
import java.io.*;
import java.util.*;
import javax.swing.filechooser.FileSystemView;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javafx.embed.swing.SwingFXUtils;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import javafx.scene.image.Image;
import javax.imageio.ImageIO;
class Iconic {
public static void main(String[] args) throws IOException{
File origin = new File("C:\\Users\\00001\\OneDrive.lnk");
Icon icn = FileSystemView.getFileSystemView().getSystemIcon(origin);
ImageIcon ico = ((ImageIcon) icn);
BufferedImage bi = new BufferedImage(
ico.getIconWidth(),
ico.getIconHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
ico.paintIcon(null,g,0,0);
g.dispose();
Image img = SwingFXUtils.toFXImage(bi,null);
File output = new File("C:\\Users\\00001\\");
BufferedImage bim = SwingFXUtils.fromFXImage(img,null);
ImageIO.write(bim,".png",output);
}
}
You are almost there, however, there are two issues in your code. Both are related to the ImageIO.write(...) method.
From the API doc of ImageIO.write(RenderedImage, String, File):
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.
The second parameter is the format name, not the file extension. So, the second argument should be "PNG", not ".png". Because ImageIO does not find any plugins that can write ".png" format, the write(...) invocation will just silently return false. I recommend always checking the return value of ImageIO.write(...).
The third parameter is the destination file to write. The path of this file has to point to a file, however yours point only to a directory. If you fix only the format name above, you'll see that most likely you get an IOException.
So, a fixed version of your writing code would like like:
File output = new File(origin.getParentFile(), origin.getName().replace(".lnk", ".png"));
if (!ImageIO.write(bi, "PNG", output)) {
System.err.println("Could not write icon");
}
I deliberately left the conversion from FX Image out. You should be able to write bi directly, without conversion to and from FX Image(unless, of course, you manipulate the image in FX).
Related
I need to convert a tiff image into a jpg one using Apache Commons Imaging.
I tried to but I can't figure out how to do it using this library.
final BufferedImage image = Imaging.getBufferedImage(new File(image));
final ImageFormat format = ImageFormats.JPEG;
final Map<String, Object> params = new HashMap<>();
return Imaging.writeImageToBytes(image, format, params);
Where image is my tiff file to be converted, but I get
org.apache.commons.imaging.ImageWriteException: This image format (Jpeg-Custom) cannot be written.
I don't understand what I'm doing wrong could someone help?
Try the use of java AWT:
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
And code:
// TIFF image file read
BufferedImage tiffImage = ImageIO.read(new File("tiff-image.tiff"));
// Prepare the image before writing - with same dimensions
BufferedImage jpegImage = new BufferedImage(
tiffImage.getWidth(),
tiffImage.getHeight(),
BufferedImage.TYPE_INT_RGB);
// Draw image from original TIFF to the new JPEG image
jpegImage.createGraphics().drawImage(tiffImage, 0, 0, Color.WHITE, null);
// Write the image as JPEG to disk
ImageIO.write(jpegImage, "jpg", new File("jpeg-image.jpg"));
Here, I am trying to send a SVG image to local server and in output I want to download that image in PNG / JPEG format.
While I have found some solutions but those are done by BATIK libraries, but in my Eclipse BATIK libraries are not supported , so I can't use the batik libraries.
Use batik library. Below is the code.
import java.io.*;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import java.nio.file.Paths;
import java.nio.file.Path;
public class svg2png {
public static void main(String[] args) throws Exception {
//Step -1: We read the input SVG document into Transcoder Input
//We use Java NIO for this purpose
String svg_URI_input = Paths.get("chessboard.svg").toUri().toURL().toString();
TranscoderInput input_svg_image = new TranscoderInput(svg_URI_input);
//Step-2: Define OutputStream to PNG Image and attach to TranscoderOutput
OutputStream png_ostream = new FileOutputStream("chessboard.png");
TranscoderOutput output_png_image = new TranscoderOutput(png_ostream);
// Step-3: Create PNGTranscoder and define hints if required
PNGTranscoder my_converter = new PNGTranscoder();
// Step-4: Convert and Write output
my_converter.transcode(input_svg_image, output_png_image);
// Step 5- close / flush Output Stream
png_ostream.flush();
png_ostream.close();
}
}
Hope it will help you.
Refer this: http://thinktibits.blogspot.com/2012/12/Batik-Convert-SVG-PNG-Java-Program-Example.html
You can also convert svg to png format without the use of Batik Transcoder.
BufferedImage input_image = null;
input_image = ImageIO.read(new File("Convert_to_PNG.svg")); //read svginto input_image object
File outputfile = new File("imageio_png_output.png"); //create new outputfile object
ImageIO.write(input_image, "PNG", outputfile);
By simply using the ImageIO library. Hope this will help!
I have the below sample code which generates a PDF file using iText.
The question I have is when I create the base64Binary by DatatypeConverter.printBase64Binary method..
I tried to copy the Sysem.out.println of "base64Binary".
Used a online base64 online decoder tool to decode the content and save it output as sample.pdf and
when I try to open the sample.pdf it shows empty. I am not sure why its behaving this way and help would be much appreciated.
But when I directly decode using java and write it to a disk file it shows the context.
Can someone help me understand why it shows blank when I try to save "base64Binary" output as sample.pdf.
Thanks.
Below is the code snippet:
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.bind.DatatypeConverter;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
/**
* Creates a PDF file in memory.
*/
public class HelloWorldMemory {
/** Path to the resulting PDF file. */
public static final String RESULT = "C:////hello_memory.pdf";
public static void main(final String[] args) throws DocumentException, IOException {
// step 1
final Document document = new Document();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final PdfWriter writer = PdfWriter.getInstance(document, baos);
document.open();
final PdfContentByte cb = writer.getDirectContent();
cb.beginText();
cb.setFontAndSize(getBaseFont(Font.NORMAL), 24);
final float exPosition = (PageSize.A4.getWidth()) / 2;
cb.showTextAligned(Element.ALIGN_CENTER, "Test No", exPosition, 670, 0);
cb.endText();
document.add(new Paragraph("Hello World!"));
document.close();
System.out.println("baos.toByteArray():" + baos.toByteArray());
final String base64Binary = DatatypeConverter.printBase64Binary(baos.toByteArray());
System.out.println("base64Binary:" + base64Binary);
final byte[] txt = DatatypeConverter.parseBase64Binary(base64Binary);
final FileOutputStream fos = new FileOutputStream(RESULT);
fos.write(txt);
fos.close();
}
private static BaseFont getBaseFont(final int fontType) {
final Font f = new Font(FontFamily.HELVETICA, 0, fontType);
final BaseFont baseFont = f.getCalculatedBaseFont(true);
return baseFont;
}
}
This question is not really related to iText or PDF. You'll have the same problem with any binary data that is base64 encoded. When using the online base64 decoder, your binary data gets corrupted somehow. Bruno already explained in his answer why this does not completely invalidate a file in case of a PDF.
The data is probably corrupted because of encoding issues. Maybe the online base64 decoder displayed the decoded data in a textarea or something and you copy/pasted it into a file? If you use a decoder that offers you a binary file for download, the result should be fine.
I tested with http://www.opinionatedgeek.com/dotnet/tools/base64decode/ (the first hit of a Google search). When I save the .bin file and rename it to .pdf, it displays as expected in a PDF viewer.
PDF is a binary file format based on the Carousel Object System (COS) syntax and the AIM (Adobe Imaging Model). The COS objects use ASCII for the file structures, but the streams for images and AIM syntax are usually binary. When you copy a PDF file without respecting the binary aspect of the file, a PDF viewer can render the document structure (the pages) based on the ASCII COS objects, but not the content (what's on the pages). This is probably what happens in your case: you're corrupting the bytes in the content streams.
I am attempting to display a .tif in Java using a minimal number of additional libraries:
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;
import javax.media.jai.widget.*;
import it.geosolutions.imageio.utilities.*;
import it.geosolutions.imageioimpl.plugins.tiff.*;
import com.sun.media.imageioimpl.common.*;
public static void main(String[] args) {
try {
File f = new File("image.tif");
BufferedImage tif = ImageIO.read(f);
ImageIcon ic = new ImageIcon(tif);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JLabel label = new JLabel(ic);
frame.add(label);
frame.setVisible(true);
} catch (IOException e) {
e.printStackTrace();
}
}
The libraries I'm using are:
jai-core-1.1.3.jar
jai-imageio-1.1.jar
imageio-ext-tiff.1.1.3.jar
imageio-ext-utilities.1.1.3.jar
From here: http://java.net/projects/imageio-ext (Downloads link on right side)
However, the displayed image is:
which is decidedly not the original image. Nor are any errors being thrown that I know of. Furthermore, the original image is fine, and doesn't change.
However, the original code is small. I don't actually use the imageio-ext imports, but the program will fail without them. I also haven't used imageio-ext before either.
Please help! I need to be able to use .tif images in Java without installing software.
If you already use all JAI/ImageIO libraries, you might want to try the following (which works fine for me):
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageDecoder;
// This function is minimal, you should add exceptions and error handling
public RenderedImage read(String filename)
FileSeekableStream fss = new FileSeekableStream(filename);
ImageDecoder decoder = ImageCodec.createImageDecoder("tiff", fss, null);
RenderedImage image = decoder.decodeAsRenderedImage()
fss.close();
return image;
}
If you need a BufferedImage instead of a RenderedImage, the only solution I found is to use this function:
public static BufferedImage Rendered2Buffered(RenderedImage image) {
BufferedImage bi = new BufferedImage(image.getWidth(), image.getHeight(), image.getSampleModel().getDataType());
bi.setData(image.getData());
return bi;
}
Be careful though, the image.getSampleModel().getDataType() usually returns a BufferedImage.TYPE_CUSTOM, which makes it impossible for the BufferedImage to be created! In my case I had to "guess" the type according to the sample size returned by image.getSampleModel().getSampleSize(0) (because I know the image format I'm working with).
If you know a better way to transform a RenderedImage to a BufferedImage, please enlighten me :)
You're correct in thinking that you need the JAI libraries to decode and use TIFF files, but even though you've imported them, you aren't actually using them!
Here is a short tutorial showing how you to create a TIFFDecodeParam object (from the JAI library), and then use that to decode (and display) a TIFF image.
You might also find the JAI API Library useful too.
I ended up going with the most-recent version of Apache-Commons Imaging (formerly Sanselan). Imaging offers out of the box support for TIFF files (I had as little bit of trouble at first, but that was solved by switching from the older Sanselan to the newer Commons Imaging).
There was a little bit of functionality I had to reverse-engineer myself (loading a single sub-TIFF at a specified width while maintaining aspect ratio):
/**
* Load a scaled sub-TIFF image. Loads nth sub-image and scales to given width; preserves aspect ratio.
*
* #param fileName String filename
* #param index Index of sub-TIFF; will throw ArrayIndexOutOfBoundsException if sub-image doesn't exist
* #param w Desired width of image; height will scale
* #return Image (BufferedImage)
* #throws IOException
* #throws ImageReadException
*/
public static Image loadScaledSubTIFF(String fileName, int index, int w) throws IOException, ImageReadException {
File imageFile = new File(fileName);
ByteSourceFile bsf = new ByteSourceFile(imageFile);
FormatCompliance formatCompliance = FormatCompliance.getDefault();
TiffReader tiffReader = new TiffReader(true);
TiffContents contents = tiffReader.readDirectories(bsf, true, formatCompliance);
TiffDirectory td = contents.directories.get(index);
Image bi = td.getTiffImage(tiffReader.getByteOrder(), null);
Object width = td.getFieldValue(new TagInfo("", 256, TiffFieldTypeConstants.FIELD_TYPE_SHORT) {/**/});
Object height = td.getFieldValue(new TagInfo("", 257, TiffFieldTypeConstants.FIELD_TYPE_SHORT) {/**/});
int newWidth = w;
int newHeight = (int) ((newWidth * ((Number)height).doubleValue()) / (((Number)width).doubleValue()));
bi = bi.getScaledInstance(w, newHeight, java.awt.Image.SCALE_FAST);
height = null;
width = null;
td = null;
contents = null;
tiffReader = null;
formatCompliance = null;
bsf = null;
return bi;
}
I have the following code:
ImageIO.write(originalImage, OUTPUT_TYPE, resultOutput);
This is an invocation of the following javax.imageio.ImageIO method:
public static boolean write(RenderedImage im,
String formatName,
File output)
throws IOException
This turns an original BMP image into a JGP output. Is it possible to also store DPI and Paper Size information in the JPEG to aid in printing operations?
I found this post for setting DPI on PNG Files. It pointed out that you should use 'metadata.mergeTree' to properly save your metadata.
With that in mind, here is some working groovy code that takes a BMP file and creates a JPG file at arbitrary DPI:
import java.awt.image.BufferedImage
import java.io.File
import java.util.Hashtable
import java.util.Map
import javax.imageio.*
import javax.imageio.stream.*
import javax.imageio.metadata.*
import javax.imageio.plugins.jpeg.*
import org.w3c.dom.*
File sourceFile = new File("sample.bmp")
File destinationFile = new File("sample.jpg")
dpi = 100
BufferedImage sourceImage = ImageIO.read(sourceFile)
ImageWriter imageWriter = ImageIO.getImageWritersBySuffix("jpeg").next();
ImageOutputStream ios = ImageIO.createImageOutputStream(destinationFile);
imageWriter.setOutput(ios);
def jpegParams = imageWriter.getDefaultWriteParam();
IIOMetadata data = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(sourceImage), jpegParams);
Element tree = (Element)data.getAsTree("javax_imageio_jpeg_image_1.0");
Element jfif = (Element)tree.getElementsByTagName("app0JFIF").item(0);
jfif.setAttribute("Xdensity", Integer.toString(dpi));
jfif.setAttribute("Ydensity", Integer.toString(dpi));
jfif.setAttribute("resUnits", "1"); // density is dots per inch
data.mergeTree("javax_imageio_jpeg_image_1.0",tree)
// Write and clean up
imageWriter.write(data, new IIOImage(sourceImage, null, data), jpegParams);
ios.close();
imageWriter.dispose();
Worked fine for me in that OSX's Preview app and Gimp both reported that the resulting image was 100 DPI. As to Paper Size...I imagine this is directly determined by DPI? I couldn't find any JPEG property that would set that particular value.
You may consider using Commons Sanselan, instead of ImageIO for this task.
See http://commons.apache.org/sanselan/whysanselan.html for more info.