Is javax.imageio.ImageIO broken? It imports some images as rotated - java

Below you will see a picture of beatiful pastry called "simit" from Turkey. It is taken from iPad 2, therefore it is a JPEG with dimensions 720*960.
The problem is, when I use javax.imageio.ImageIO.read method, the image it strangely imports is to a BufferedImage rotated to left and becomes 960*720.
I reproduced this in my Sun JVM 1.6.0_29 on OS X and Sun JVM 1.6.0_26 on Debian. Here's the code:
public class Main {
public static void main(String[] args) throws Exception {
FileInputStream stream = new FileInputStream(new File("IMG_0159.JPG"));
BufferedImage img = ImageIO.read(stream);
System.out.println("width:" + img.getWidth() + " height:"
+ img.getHeight());
}
}
It outputs width:960 height:720, and when I save this output image, it is rotated to left as I told before. If you would like to reproduce this, download code and picture from here and run the following commands to build and run:
javac Main.java && java Main
NOTE: You may see the JPG in the archive as already rotated, however it appears 720*960 on OS X, iPad, iPhone and as you see above, it is uploaded correctly to imgur.com. And it is also opened correctly in Adobe Photoshop, uploaded to Facebook correctly etc.
What could be the problem here?

The photo was probably taken holding the iPad in portrait mode, and therefore contains EXIF orientation information, which ImageIO ignores, but you can use other libraries, like Apache Sanselan to correctly handle it.
So the image itself is 960x720, but MacOS, ImgUR, Facebook etc correctly take the EXIF info into account.
And simit looks delicious :)

Related

Sikuli on Java does not recognize images

I have been trying to automatize some tasks on my computer and did choose Sikuli from Java to do so (I work with Java everyday and didn't know any automation tool using java, sikuli was the first I found). I use java with maven and eclipse as IDE. I have added Sikuli as a Maven dependency.
<dependency>
<groupId>com.sikulix</groupId>
<artifactId>sikulixapi</artifactId>
<version>2.0.5</version>
</dependency>
I tried to do some simple stuff. I did a few screenshots of parts of my screen using windows' screenshot tool, and wanted sikuli to hover it. It works quite fine for one image, but not at all for the others. It seems that the bigger the image the better it works as I did not have success for any small images. The one working is a screen of a whole window (reduced to ~1/4 of my screen).
I also tried to find a button inside this window, to find the windows logo on bottom left, to find a screen of my package explorer, but none work correctly.
I played with similar() using various values, but it didn't improve the results. In some cases (button inside the window) it did find a result for some low similar value, but it was another button. The weird part is : its finding this other button which is bright blue, while the one i'm looking for is purple.
My pc background never changes, I did some screen.highlight() and its looking at the correct screen (dual screen). It's not an issue with the path to images (already solved this one).
Do you have any idea of what I could try ? I have read about people having different success rate depending on whether they were using Sikuli IDE or another IDE. So maybe I could give sikuli IDE a try.
I can give code samples as soon as I am back home.
The code I'm using to test :
public class CleanTest {
static Screen screen = new Screen();
public static void main(String[] args) throws FindFailed, AWTException, IOException, InterruptedException {
String pathYourSystem = System.getProperty("user.dir") + "\\";
System.out.println(pathYourSystem);
Pattern pLauncher = new Pattern(pathYourSystem+"img\\full_launcher.PNG").similar(0.9d);
Desktop.getDesktop().open(new File("path_to_an_exe_opening_a_launcher"));
screen.wait(pLauncher, 300);
screen.mouseMove();
System.out.println("launcher found");
}
}
It works with the "full launcher" image, but it doesn't find a sub-part of the launcher (a button). I tried to make some code to test if there was some threshold for the similar parameter :
double similarValue = 1d;
Pattern pLauncher = new Pattern(pathYourSystem+"img\\the_button.PNG").similar(similarValue);
Desktop.getDesktop().open(new File("path_to_an_exe_opening_a_launcher"));
while(!screen.has(pLauncher)) {
similarValue-=0.1;
pLauncher = new Pattern(pathYourSystem+"img\\login.PNG").similar(similarValue);
}
System.out.println(similarValue);
screen.mouseMove();
it finds something at around 0.5, but it's a totally different button.
Thank you !
EDIT: if someone has the same issue, try to use sikulix IDE to take the screenshots. It works with the screenshots taken by the IDE.
This is a simple test, that completely stays within the SikuliX features.
import org.sikuli.basics.Debug;
import org.sikuli.script.*;
public class SikulixTest {
public static void main(String[] args) {
System.out.println("SikulixTest");
Screen scr = new Screen();
// craete an image to be searched on the screen
Image img = new Image(scr.userCapture());
// try to find it
Match mImg = scr.exists(img);
if (mImg != null) {
// show sthg. when found
Debug.info("%s", mImg);
mImg.highlight(2);
}
}
}
This is RaiMan from SikuliX

How do I supply a Color Model to a .tiff image in Java when the image does not provide a Color Model to be used?

I am fairly new to Java, and so some of the classes like Color Model and JAI are not familiar to me. I have a tiff image I am reading into a program in Java. This is my read-in code:
BufferedImage img = null;
String input[] = {"LE70160412002112EDC00_sr_band5", "LE70160412002144EDC00_sr_band5"};
String filetype = "tif";
File file = new File(input[0] + "output.csv");
int numFiles = 0;
while (numFiles < 2){
if (filetype == "tif"){
FileSeekableStream stream = new FileSeekableStream(new File(input[numFiles] + ".tif"));
TIFFDecodeParam decodeParam = new TIFFDecodeParam();
decodeParam.setDecodePaletteAsShorts(true);
ParameterBlock params = new ParameterBlock();
params.add(stream);
RenderedOp image1 = JAI.create("tiff", params);
img = image1.getAsBufferedImage();
}
}
To be clear, other things are done further down in the while loop that I excluded such that the files are not overwriting each other. The problem I am having is not being able read in the file and get further into the loop. I had a tiff file that only had black and white pixels (0 or 255 red value for all pixels), and the code ran correctly because the file supplied the Color Model. The new tiff file I am trying to use is a greyscale picture (0 to 255 red value for all pixels), and every time I run the code it gives me the following error message:
Exception in thread "main" java.lang.IllegalArgumentException: No ColorModel is supplied and the image ColorModel is null.
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2500)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2546)
at Soda.DoStuff.doStuff(DoStuff.java:60)
at Soda.Driver.main(Driver.java:6)
My first instinct given the error message is to create a new Color Model. There may also be a better way to use JAI to import the tiff file such that it supplies the Color Model for the greyscale image. My end goal is to get the red value for each pixel in the image, so I do not want the data coming in to be altered from it's original form.
Any help I can get would be much appreciated. I am open to any suggestions.
EDIT:
Someone commented to try and use the getDefaultColorModel class inside the PlanarImage library, so I changed the bottom line of the code to this:
cm = PlanarImage.getDefaultColorModel(0, 1); //
img = image1.getAsBufferedImage(null, cm);
This also did not completely work but provided a different error message:
Exception in thread "main" java.lang.IllegalArgumentException: SampleModel and ColorModel parameters must be non-null.
at com.sun.media.jai.util.JDKWorkarounds.areCompatibleDataModels(JDKWorkarounds.java:363)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2505)
at Soda.DoStuff.doStuff(DoStuff.java:64)
at Soda.Driver.main(Driver.java:6)
I have extensively read through https://docs.oracle.com/cd/E17802_01/products/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/PlanarImage.html to learn about the PlanarImage class, but I still cannot figure out how to properly format a ColorModel. (0,1) creates a color model with 8 pixel bits and 1 component. I also tried with (1,1) which creates a color model with 16 pixel bits and 1 component. Both provided the same error message above.
EDIT2: Unfortunately, I cannot link the image itself. However, I can tell you how I got the image from USGS. Forewarning, getting this image requires you to make a free account, and then afterwards you have to 'order' the picture from USGS, which is simply they need to process the request and give a download link for a zip file. It WILL take some time before you can actually access the picture. I also suggest making the account first because it will not let you start the image checkout process until you have an account made.
Using this link, http://earthexplorer.usgs.gov/, you pick a point on the map, then set the date range so that it ends on 12/31/2002 (the start date does not matter). The go to the Data set tab where under the "Landsat Archive" bullet, you will hit the checkbox for "Landsat Surface Reflectance - L7 ETM+". Hit OK on the dialogue, then hit "Results" at the bottom of the screen.
Once you have signed into your account and done this search, you should see many images on the left side of your screen with similar names to the filenames in my code above. You want to hit the shopping cart next to one of the images (You only need one, my whole project required 2, but for the purposes of reading in the file, that's not necessary). The shopping cart should turn green. Then in the top right corner there is a link to an Item Basket. You hit "Proceed to Checkout" and "Submit Order" on successive screens, and then you wait for an email from USGS.
Finally unzip the file, and you should have about 10 images. As you can see in the code, I am using the image with the name "sr_band5", but I believe any of the bands are greyscale which I cannot read in. Hope this can help.

Java Icon Image Maximum File Size

I am working on a chess game on Java. I have been importing images onto Eclipse and then assigning them to ImageIcons, and then subsequently assigning these ImageIcons onto buttons to form a grid.
At one point three out of my four bishop images were not being assigned to their respective buttons and so I looked at the file size and it turns out that the sizes of the three images that weren't being assigned were ~1,100KB, ~1,200KB, and ~40KB. The image that was being assigned to the button was around 25KB. I thought this was odd (especially since all four images are very similar) so I exported the three problematic images in a lower resolution (all under 30KB), and then re-imported them into Eclipse. When I ran my program again they were assigned to the right buttons and everything ran smoothly again.
The buttons that I am using are all 75 x 75 pixels, and the pixels were the same for each image (75 x 75), so I am confused why this happened. I looked for any questions relating to this, but I could not find any. If anyone could help explain why this could happen to me that would be very helpful so I can avoid this problem in the future.
I've definitely loaded images much bigger than that into ImageIcons and other components, so I suspect that your issue is that when you are assigning the Image to the ImageIcon before the Image is fully loaded. You can use MediaTracker to help solve this problem. From ImageIcon:
/** * Loads an image into memory */
public static Image loadImage(String fn){
try {
Image image=java.awt.Toolkit.getDefaultToolkit().createImage(fn);
MediaTracker tracker=new MediaTracker(lblForFM); tracker.addImage(image,0);
tracker.waitForID(0);
if (MediaTracker.COMPLETE != tracker.statusID(0,false)) throw new
IllegalStateException("Unable to load image from " + fn);
else return image; } catch ( InterruptedException e) {
throw new RuntimeException("Interrupted while loading image from " + fn,e);
}
}
I recommend using png for transparent images and icons, jpg for non-transparent images - and only if compression artifacts don't matter (lossless JPEG sadly isn't widely spread). bmp is one of the worst file formats out there if it comes to file size. As suggested by the others, load images in java with the ImageIO API:
public class Program {
public static void main(String[] args) {
InputStream imageSource = Program.class.getResourceAsStream("bishop"); // may be a URL, File or ImageInputStream instead
try {
BufferedImage bishopImage = ImageIO.read(imageSource); // read image
ImageIcon bishopIcon = new ImageIcon(bishopImage); // use adapter for Icon interface
System.out.println(bishopIcon); // do something with it
} catch (IOException e) {
e.printStackTrace(); // read failed
}
}
}

Applying sobel filter on jpg picture with OpenCV 2.4.10 in Java

I'm trying to add sobel operator on a jpg picture with Java. I found example here: http://www.tutorialspoint.com/java_dip/applying_sobel_operator.htm but it doesn't work. Instead it prints black image. Could someone explain to me what I did wrong, please? Other imgproc functions works well.
Here is my code:
Mat sourceImage = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_GRAYSCALE);
Mat destinationImage = new Mat(sourceImage.rows(), sourceImage.cols(), sourceImage.type());
Mat kernel = new Mat(kernelSize,kernelSize, CvType.CV_32F){
{
put(0,0,-1);
put(0,1,0);
put(0,2,1);
put(1,0-2);
put(1,1,0);
put(1,2,2);
put(2,0,-1);
put(2,1,0);
put(2,2,1);
}
};
Imgproc.filter2D(sourceImage, destinationImage, -1, kernel);
Highgui.imwrite(destinationPath, destinationImage);
//display
new ShowImage(sourcePath, sourceImage);
new ShowImage(destinationPath, destinationImage);
First up, is there a reason why you're not using
Imgproc.Sobel(Mat src, Mat dst, int ddepth, int dx, int dy);
I'm not sure of the Java syntax used here. When does the block of puts get executed? Is it assumed to part of a constructor for a subclass of Mat that you define ? Having said that, assuming that this does what it looks like it's intended to do then it's possible that your output file type is not correctly specified; what is the value of destinationPath ?
Have you tried opening the saved file in an alternative image viewer to determine if it's the ShowImage() code or the saved file that's at fault ?
Have you tried opening the saved file in a hex editor to see if it has 'sensible' looking values or is all zeros ?

converting webpage into jpeg image using java

I am building a web application, in Java, where i want the whole screenshot of the webpage, if i give the URL of the webpage as input.
The basic idea i have is to capture the display buffer of the rendering component..I have no idea of how to do it..
plz help..
There's a little trick I used for this app:
count down demo app http://img580.imageshack.us/img580/742/capturadepantalla201004wd.png
Java application featuring blog.stackoverflow.com page ( click on image to see the demo video )
The problem is you need to have a machine devoted to this.
So, the trick is quite easy.
Create an application that takes as
argument the URL you want to fetch.
Then open it with Desktop.open( url
) that will trigger the current
webbrowser.
And finally take the screenshot with
java.awt.Robot and save it to diks.
Something like:
class WebScreenShot {
public static void main( String [] args ) {
Desktop.getDesktop().open( args[0] );
Robot robot = new Robot();
Image image = robot.createScreenCapture( getScreenResolutionSize() );
saveToDisk( image );
}
}
This solution is far from perfect, because it needs the whole OS, but if you can have a VM devoted to this app, you can craw the web and take screenshots of it quite easy.
The problem of having this app as a non-intrusive app is that up to this date, there is not a good html engine renderer for Java.
For a pure-java solution that can scale to support concurrent rendering, you could use a java HTML4/CSS2 browser, such as Cobra, that provides a Swing component for the GUI. When you instantiate this component, you can call it's paint(Graphics g) method to draw itself into an off-screen image
E.g.
Component c = ...; // the browser component
BufferedImage bi = new BufferedImage(c.getWidth(), c.getHeight(), TYPE_INT_RGB)
Graphics2d g = bi.createGraphics();
c.paint(g);
You can then use the java image API to save this as a JPG.
JPEGImageEncoder encoder = JPEGCodec.createEncoder(new FileOutputStream("screen.jpg"));
enncoder.encode(bi); // encode the buffered image
Java-based browsers typically pale in comparison with the established native browsers. However, as your goal is static images, and not an interactive browser, a java-based browser may be more than adequate in this regard.

Categories

Resources