Java Icon Image Maximum File Size - java

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
}
}
}

Related

Can't Change Default Java Image (JFrame.setIconImage)

I am trying to change the icon of the Java application but nothing seems to work.
I am trying to get image from resources path using:
getClass().getResource("/AppIcon.png")
Sometimes I get an error like URL not found.
The image that is used for the Form's icon can be any image but must be loaded as an Image type (not of ImageIcon type). The JFrame#setIconImage() method will auto-size the image loaded. Here just a couple ways. These examples assume that the code resides in a class which extends JFrame:
Example #1:
try {
/* For a Form's title bar icon....
Don't use this for animated .gif images otherwise your GUI will
freeze. I'm not exactly sure why but it seems as though the gif
frames continuously cycle as though in an infinite loop. If you
want to use an animated .gif image as a Form's title bar icon
then don't use Toolkit, use ImageIO.read() instead since it will
only utilize the first gif frame as the image. */
// Be sure to set the path string to your specific resources directory.
this.setIconImage(java.awt.Toolkit.getDefaultToolkit()
.getImage(getClass().getResource("/resources/images/Apple/png").getFile()));
}
catch (java.lang.NullPointerException ex) {
// Do what you want with caught exception.
ex.printStackTrace();
}
Example #2:
try {
/* Can be used to also display an animated gif for the Form's Title
bar icon but only the first gif frame is utilized. */
// Be sure to set the path string to your specific resources directory.
File pathToFile = new File(getClass().getResource("/resources/images/Apple.png").getFile());
Image image = ImageIO.read(pathToFile);
this.setIconImage(image);
}
catch (IOException ex) {
// Do what you want with caught exception.
ex.printStackTrace();
}
UPDATE:
As stated by #AndrewThompson in comments, the two above examples will not work as expected from a JAR file. They will work if run through the IDE however which in reality is no good except for testing. To use the two examples above in a distributive JAR file then also see Example #3 and Example #4:
Example #3:
try {
/* For a Form's title bar icon.... To be used in a distributive JAR.
Don't use this for animated .gif images otherwise your GUI will
freeze. I'm not exactly sure why but it seems as though the gif
frames continuously cycle as though in an infinite loop. If you
want to use an animated .gif image as a Form's title bar icon
then don't use Toolkit, use ImageIO.read() instead since it will
only utilize the first gif frame as the image. */
// Be sure to set the path string to your specific resources directory.
java.net.URL url = getClass().getResource("/resources/images/Apple.png");
this.setIconImage(java.awt.Toolkit.getDefaultToolkit().getImage(url));
}
catch (java.lang.NullPointerException ex) {
// Do what you want with caught exception.
ex.printStackTrace();
}
Example #4:
try {
/* For a Form's title bar icon.... To be used in a distributive JAR.
Can be used to also display an animated gif for the Form's Title
bar icon but only the first gif frame is utilized. */
// Be sure to set the path string to your specific resources directory.
java.net.URL url = getClass().getResource("/resources/images/Apple.png");
Image image = ImageIO.read(url);
this.setIconImage(image);
}
catch (IOException ex) {
// Do what you want with caught exception.
ex.printStackTrace();
}
Don't even bother with Examples #1 and #2, they now just remain here for reference. Just use either Example #3 or Example #4. Both will work in the IDE or a distributive JAR file.
Solution;
Everything works for windows but I am using Mac :D
So I started to look around Taskbar class comes with awt package and found the solution (Thanks to flohall)
try {
var image = new ImageIcon(Objects.requireNonNull(Main.class.getResource("/AppIcon.png")));
frame.setIconImage(image.getImage());
if (System.getProperty("os.name").startsWith("Mac") || System.getProperty("os.name").startsWith("Darwin")) {
Taskbar taskbar = Taskbar.getTaskbar();
try {
taskbar.setIconImage(image.getImage());
} catch (final UnsupportedOperationException e) {
System.out.println("Can't set taskbar icon.");
} catch (final SecurityException e) {
System.out.println("Warning. Can't set taskbar icon due to security exceptions.");
}
}
} catch (NullPointerException e) {
e.printStackTrace();
}
So we are telling the taskbar to change its icon using built-in awt Taskbar class on taskbar.setIconImage(image.getImage());. And that solves most of the things I've needed for.

javaFx Image Height and Width got backwards?

I am making a game in javaFx. The way entities in my game is rendered is dependent on one of their fields called "angle", like this:
gc.save();
gc.transform(new Affine(new Rotate(angle, getCenterX(), getCenterY())));
gc.drawImage(image, x, y);
gc.restore();
"Gc" is the GraphicsContext. The getCenter methods will use the height and width of the images. However, the images are not rendered properly. I ran some tests and found that when I use the get Width method, it actually returns the height of the image. When I call the get Height method, it returns the width. My guess is that it's because the png images I use have been rotated 90 degrees in respect to their original state. However, when I go to preview and look at their size, it seems that everything is fine. I tried duplicating the images, but it doesn't really work. Any ideas how to fix this? I don't have a verifiable code example because I believe this question is more related to properties of png files and javaFx's Image methods than my program's logic.
Here is the verifiable code example:
import javafx.embed.swing.JFXPanel;
import javafx.scene.image.Image;
public class TestImage {
public static void main(String[] args) {
// TODO Auto-generated method stub
JFXPanel jfxPanel = new JFXPanel();
Image BLUE01 = new Image("/blue01.png");
System.out.println("height : "+ BLUE01.getHeight());
System.out.println("wdith : "+ BLUE01.getWidth());
}
}
And here is the image:
It seems that the problem comes from not my code but my use of IDE... It turns out that after I edit or add image in my resource folder, I need to click "refresh" in eclipse...

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.

processing copy/duplicate resize issue

not posted before, so be patient.
I'm having an issue in the processing IDE with copying PImages and then resizing. Resizing a copy of an image also appears to resize the original.
void setup(){
size(10,10,P2D);
PImage img;
img = loadImage("nickwire.jpg");
println(img.width);
PImage dupe;
dupe=img;
dupe.resize(10,10);
print(img.width);print("\t");println(dupe.width);
}
//console outputs:
//263
//10 10
//I'm expecting
//263
//263 10
What am I doing wrong?
You are not creating a copy of your image, you are creating a new reference and pointing it to the same image.
In order to copy the image to the new reference, take a look at the PImage#get() method.

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

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 :)

Categories

Resources