Java Image Colorprofile Issue - java

I resize my images via imageio but images which use the Color profile
sRGB IEC61966-2.1- IEC 61966-2.1 Default RGB colour space turn out green-ish:
Source Image:
Output Image:
The strange thing is that it seems that imageio is somehow breaking during runtime. A restart of my JVM somehow cures the issue and it does not happen for a while. Other images which don't use this special Colorprofile resize just fine.
I'm running JDK 1.8.0_25 and use the following image jars:
jai_imageio-1.1.jar
jmage-0.7-2.jar
image4j-0.7.jar
jai_codec-1.1.3.jar
jai_core-1.1.3.jar
Has someone maybe encountered this issue before?

Here's the sample code that works for me. I'm using a slightly more updated Java version.
$ java -version
java version "1.8.0_121"
Source code:
public static void main(String[] args) throws IOException {
BufferedImage image = ImageIO.read(new File(args[0]));
BufferedImageOp op = new AffineTransformOp(AffineTransform.getScaleInstance(1.43, 1.43), AffineTransformOp.TYPE_BICUBIC);
Rectangle bounds = op.getBounds2D(image).getBounds();
// NOTE: Passing null as last param to filter() works fine, but creates a destination
// image (TYPE_INT_ARGB) that JPEGImageWriter will write in a way other software
// interprets as CMYK rather than ARGB. It does not look like your result image, though...
// And, it works fine if you write the image as PNG, even if passing null.
BufferedImage result = op.filter(image, new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_3BYTE_BGR));
ImageIO.write(result, "PNG", new File("foo.png"));
ImageIO.write(result, "JPEG", new File("foo.jpg"));
}
The resulting foo.jpg looks like this:

Related

Why use ImageIO can't get BufferedImage from URL

imageURL: https://fbexternal-a.akamaihd.net/safe_image.php?d=AQBB77GLfY75FNWL&w=720&h=2048&url=http%3A%2F%2Fwww.facebook.com%2Fads%2Fimage%2F%3Fd%3DAQI0duFYFcmydWNutbwmSk2DfOmHcDrhPfsMJTUoEObbWkVzYUtrHgCuN_LFrWcPRzJi6jPgbn80oFs0Kj_WrdROjdnJkjbnS5-UJv9l9cJyhKCWS-lr-MXlc263Ul3Txe-VFqXfRrA6BOjt4DF-Sww2&ext=best
URL url = new URL(imageURL);
BufferedImage image = ImageIO.read(url);
or
URL url = new URL(imageURL);
BufferedImage image = ImageIO.read(url.openStream());
the result image is null? why?
ImageIO.read(URL) does support reading images from URL like you describe, however, it does support only a limited set of image formats. Built-in formats are JPEG, PNG, GIF, BMP and WBMP. There are plugins for many other formats, like TIFF, JPEG 2000, etc.
The problem is that the linked image is not in any of the built-in formats, it's in WEBP format, a new image format created by Google, and which does not have very widespread use yet. The reason it displays fine in your browser (and mine :-) ), is most likely that you are using Chrome, and Chrome has built-in support for WEBP.
There's at least one WEBP ImageIO plugin available. If you build and install this plugin, your code above should work and read the image just fine. There should be no need to invoke ImageIO.scanForPlugins() if the plugin is on class path when you launch your application.
Make sure the URL your provided is linking to a valid image file format such as jpg, png, bmp and so on.
Your current URL is linking to a .php file which is obviously not an image.
For example:
public static void main(String[] args)
{
Image image = null;
try {
URL url = new URL("https://s-media-cache-ak0.pinimg.com/236x/ac/bb/d4/acbbd49b22b8c556979418f6618a35fd.jpg");
image = ImageIO.read(url);
} catch (IOException e) {
e.printStackTrace();
}
JFrame frame = new JFrame();
frame.setSize(236, 306);
frame.add(new JLabel(new ImageIcon(image)));
frame.setVisible(true);
}
When I open the link in Firefox, it attempts to download a file called "safe_image.php". It works in Google Chrome, so there's something weird going on in the headers or something for that URL. Is there any way you can host the image elsewhere?
Edit: Your image appears to be in the WebP format. ImageIO does not support this format natively, so you will need a library like webp-imageio.
Install that library and see if your code works. ImageIO should automatically find the plugin when you run ImageIO.scanForPlugins().

Is there an efficient way to crop out PDF and save as image (.JPG) via java program?

I am Currently using ICEPDF to render PDF files and display it in my java Swing application (in Internal Frame). Now I want to add crop features to my Java application. Like, if I click a button, I can drag required portion of PDF and save it as Image in my local storage.
Is there an efficient way to crop out PDF and save as image (.JPG) via java program?
Ghost4J library (http://ghost4j.sourceforge.net), is your best option:
3 simple step:
Load PDF files:
PDFDocument document = new PDFDocument();
document.load(new File("test.pdf"));
Create the renderer:
SimpleRenderer renderer = new SimpleRenderer();
// set resolution (in DPI)
renderer.setResolution(600);
Render:
List<Image> images = renderer.render(document);
Then you can do what you want with your image objects, for example, you can write them as JPG like this:
for (int i = 0; i < images.size(); i++) {
ImageIO.write((RenderedImage) images.get(i), "jpg", new File((i + 1) + ".jpg"));
}
Ghost4J uses the native Ghostscript API so you need to have a Ghostscript installed.
EDIT: investigating a bit, if you convert the PDF to Image you won't have much problem to crop them:
BufferedImage is a(n) Image, so the implicit cast that you're doing in the second line is able to be compiled directly. If you knew an Image was really a BufferedImage, you would have to cast it explicitly like so:
Image image = ImageIO.read(new File(file));
BufferedImage buffered = (BufferedImage) image;
Then you can crop it with BufferedImage::getSubimage method:
private BufferedImage cropImage(BufferedImage src, Rectangle rect) {
BufferedImage dest = src.getSubimage(rect.x, rect.y, rect.width, rect.height);
return dest;
}

How to load an image in Java using toolkit and new URL

I need to use a JPEG image in my Java applet.
In my applet class, I define the image name and create an object to ImageBuffer class.
String iname= "image1.jpg";
b = new ImageBuffer(iname,this);
In the ImageBuffer class, I call
Image image = null;
image = Toolkit.getDefaultToolkit().getImage(new URL(applet.getCodeBase(),fileName));
While this does not flag an error and image is not null anymore, it does not initialize image correctly. The height and width are -1. The url of the path however appears to be correct : /C:/Users/..../image1.jpg
How do I correctly load the image? It is in the bin file of my Eclipse project currently.
The height and width are -1.
Use a MediaTracker to monitor the asynchronous loading progress of the image. Alternately use ImageIO to load the image prior to the next code line.
If the image is placed in the correct location, then this would fix it
image = new ImageIcon(Toolkit.getDefaultToolkit().getImage(new URL(applet.getCodeBase(),fileName))).getImage();
If the code returns a NullPointerException it means the image is not placed in the correct directory.

How to get the window size of the active/focused application using java?

I have a program written in JAVA that creates a JPG file at a specified path whenever PRINTSCREEN is pressed. This program runs in background and uses the JIntellitype API.
My problem is that:
screensize = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
is the only available function I could find to get the screen size which I later use to get a buffered image like this:
bf = screenRobot.createScreenCapture(screensize);
where bf is a BufferedImage data type.
Is there any way that I could get the screensize of the window that is currently active so that unwanted content is not saved in the JPG file?
Frame.getX()
Frame.getY()
Frame.getWidth()
Frame.getHeight()

Java: Reading images and displaying as an ImageIcon

I'm writing an application which reads and displays images as ImageIcons (within a JLabel), the application needs to be able to support jpegs and bitmaps.
For jpegs I find that passing the filename directly to the ImageIcon constructor works fine (even for displaying two large jpegs), however if I use ImageIO.read to get the image and then pass the image to the ImageIcon constructor, I get an OutOfMemoryError( Java Heap Space ) when the second image is read (using the same images as before).
For bitmaps, if I try to read by passing the filename to ImageIcon, nothing is displayed, however by reading the image with ImageIO.read and then using this image in the ImageIcon constructor works fine.
I understand from reading other forum posts that the reason that the two methods don't work the same for the different formats is down to java's compatability issues with bitmaps, however is there a way around my problem so that I can use the same method for both bitmaps and jpegs without an OutOfMemoryError?
(I would like to avoid having to increase the heap size if possible!)
The OutOfMemoryError is triggered by this line:
img = getFileContentsAsImage(file);
and the method definition is:
public static BufferedImage getFileContentsAsImage(File file) throws FileNotFoundException {
BufferedImage img = null;
try {
ImageIO.setUseCache(false);
img = ImageIO.read(file);
img.flush();
} catch (IOException ex) {
//log error
}
return img;
}
The stack trace is:
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:58)
at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:397)
at java.awt.image.Raster.createWritableRaster(Raster.java:938)
at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1056)
at javax.imageio.ImageReader.getDestination(ImageReader.java:2879)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:925)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:897)
at javax.imageio.ImageIO.read(ImageIO.java:1422)
at javax.imageio.ImageIO.read(ImageIO.java:1282)
at framework.FileUtils.getFileContentsAsImage(FileUtils.java:33)
You are running out of memory because ImageIO.read() returns an uncompressed BufferedImage which is very large and is retained in the heap because it is referenced by the ImageIcon. However, the images returned by Toolkit.createImage remain in their compressed format (using the private ByteArrayImageSource class.)
You cannot read a BMP using Toolkit.createImage (and even if you could it would still remain uncompressed in memory and you would probably run out of heap space again) but what you can do is read the uncompressed image and save it in a byte array in compressed form, e.g.
public static ImageIcon getPNGIconFromFile(File file) throws IOException {
BufferedImage bitmap = ImageIO.read(file);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
ImageIO.write(bitmap, "PNG", bytes);
return new ImageIcon(bytes.toByteArray());
}
That way the only time the uncompressed bitmap must be held in memory is when it is being loaded or rendered.
Have you tried this?
ImageIcon im = new ImageIcon(Toolkit.getDefaultToolkit().createImage("filename"));
It couldn't be that you indeed just run out of memory? I mean, does the error still occur if you run java with, say, -Xmx1g ?

Categories

Resources