Some years ago I took a couple of courses in programming. Now I'm in a situation where some very basic image processing might save me loads of time. Unfortunately I'm a bit stuck trying to read an image. I haven't done this before and basically just copied some code I found, but I get "javax.imageio.IIOException: Can't read input file!". I've tried moving the image "Test.jpg" and change the path. I don't understand what is causing the issue. I use macOS, not sure if this is relevant.
import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
public class MyImage{
public static void main(String args[])throws IOException{
BufferedImage image = null;
File f = null;
try {
f = new File("Users/simonprobert/eclipse-workspace/LineLengthCounter/src/Test.jpg");
image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
image = ImageIO.read(f);
System.out.println("Reading complete.");
} catch(IOException e){
System.out.println("Error: "+e);
}
}
}
(Currently I'm just trying to read the image, the rest is not important at this point)
Related
So I have a class that utilizes java's robot class to take a screen picture and make 5 smaller pictures from it.
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
public class screencap {
static Rectangle rectangle = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
public ArrayList<BufferedImage> get() throws AWTException, IOException {
ArrayList<BufferedImage> array = new ArrayList<BufferedImage>();
Robot robot = new Robot();
BufferedImage bufferedImage = robot.createScreenCapture(rectangle);
BufferedImage img1 = bufferedImage.getSubimage(481,1039,190,31);
BufferedImage img2 = bufferedImage.getSubimage(682,1039,190,31);
BufferedImage img3 = bufferedImage.getSubimage(883,1039,190,31);
BufferedImage img4 = bufferedImage.getSubimage(1085,1039,190,31);
BufferedImage img5 = bufferedImage.getSubimage(1286,1039,190,31);
array.add(img1);
array.add(img2);
array.add(img3);
array.add(img4);
array.add(img5);
return array;
}
}
So what I can do is use the class above to get an array of 5 buffered image like so
screencap nsc = new screencap();
try {
ArrayList<BufferedImage> bfl = nsc.get();
} catch (AWTException | IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
The problem that I encountered was that the code worked flawlessly when I ran it on eclipse but when I exported it as an executable jar file it didn't work and couldn't even throw an error. I'm pretty sure the code at fault here is screencap.get() but I don't know how to fix it. Can someone tell me what went wrong? Thanks in advance.
SOLVED: I turned off window scaling. Apparently it messes with my program somehow.
Also, when I execute the program from cmd it works even if window scaling is on
#ArnaudClaudel thank you for suggesting I use cmd
The reason my program didn't work is that I have window scaling turned on to 125%. It made my exported program look bigger than it supposed to be, making pictures look blurry and it messes with the function in the question. I fixed it by turning off window scaling. Another solution is to execute the jar file from the cmd.
I am participating in a project where we build an app which solves Rubiks' cubes. Initially we started with a desktop app using JavaFX but we decided to switch over to an Android app.
Since I already implemented a working model at least for color recognition, I wanted to reuse that and just build another UI around it. That is where I am stuck right now because I cannot even get Android's bitmap API to work. Unfortunately it looks like I need to stick with it since Swing/AWT/JavaFX image libraries are not available.
So I implemented a JUnit test which I cleaned up a bit:
package de.uniks.rubiksapp;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
#RunWith(RobolectricTestRunner.class)
public class TestBitmap {
#Test
public void testBitmap() {
Resources resources = RuntimeEnvironment.application.getResources();
InputStream testImageStream = resources.openRawResource(R.drawable.test_front);
Bitmap testImageBitmap = BitmapFactory.decodeStream(testImageStream);
//Bitmap testImageBitmap = BitmapFactory.decodeResource(resources, R.drawable.test_front);
// --- Pixel readout would be here --- //
System.out.println(testImageBitmap.getWidth() + "x" + testImageBitmap.getHeight() + "px");
FileOutputStream out = null;
try {
out = new FileOutputStream("test.png");
testImageBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
My problem currently is that the bitmaps I get from BitmapFactory seem to be corrupted. When I am trying to read specific pixels using Bitmap.getPixel(), they are always black. So I tried saving the image back to disk which works but the resulting files are only around 40 bytes large and cannot be opened.
Initially, I tried using Bitmap.decodeResource() instead of Bitmap.decodeStream() but that always returns images with a size of 100x100px, although my source images are 1240x800px large. Even when I use Bitmap.Options and set inScaled = false. At least the size is correct when using Bitmap.decodeStream().
Thanks for any help!
ImageIO.read() just seems to be stuck in an infinite loop.
My code:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Texture {
BufferedImage _img;
public Texture(String path) {
try {
_img = ImageIO.read(new File(path));
} catch (final IOException e) {
e.printStackTrace();
}
}
}
Other class:
private Texture _tex;
_tex = new Texture("/res/img.png");
I have tried loading the image this URL and File, none works.
I am using eclipse, on a mac, and I am using LWJGL 3 if that has anything to do with anything.
Hope you can help me! :-)
Instead of using a File, try using an input stream like this:
InputStream stream = Texture.class.getResourceAsStream(path);
_img = ImageIO.read(stream);
I'm actually experiencing a similar issue, but it's related to the creation of BufferedImages.
I can not find any documenration on this library (https://code.google.com/p/sfntly/). I've been taking stabs at it for 2 days now. I'm trying to convert any font that gets uploaded to "WOFF" format.
Could someone shed some light?
I successfully converted my TTF into a WOFF file by following these steps:
Download and install ant following "The Short Story" steps (http://ant.apache.org/manual/install.html#getBinary)
Download SFNTLY via SVN checkout (https://code.google.com/p/sfntly/source/checkout) and followed the steps contained into the file "sfntly\java\quickstart.txt"
Created a new java project and imported the following four jars I created following the previous steps into my project:
sfntly.jar
woffconverter.jar
guava-16.0.1.jar
I slightly tweaked display_name code which contained a few syntax mistakes.
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import com.google.common.io.Files;
import com.google.typography.font.sfntly.Font;
import com.google.typography.font.sfntly.FontFactory;
import com.google.typography.font.sfntly.data.WritableFontData;
import com.google.typography.font.tools.conversion.woff.WoffWriter;
public class Main {
public static void main(String[] args) {
WoffWriter ww = new WoffWriter();
FontFactory fontFactory = FontFactory.getInstance();
byte[] bytes;
try {
bytes = Files.toByteArray(new File("C:\\FontName.TTF"));
Font font = fontFactory.loadFonts(bytes)[0];
WritableFontData wfd = ww.convert(font);
FileOutputStream fs = new FileOutputStream("out.fnt");
wfd.copyTo(fs);
fs.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
After reading the source code of SFNTLY I am no expert in sfntly, so use my answer at your risk :).
I would convert the font with WoffWriter#convert() to writeable font data, then copy the wfd to outputstream.
WoffWriter ww = new WoffWriter();
WriteableFontData wfd = ww.convert(yourFont);
try {
FileOutPutStream fs = new FileOutputStream("out.fnt");
wfd.copyTo(fs, wfd);
fs.close();
} catch (IOException e) {
}
I want to load large images (18000 x 18000) to my application. If i use BufferedImage with type int_rgb, I need around 1235mb of heap memory to load. This is a very high amount of memory, and end users will likely have less ram (1GB or less).
On my development PC, when I load the image from MyEclipse IDE, it throws an out of memory Exception. When i pack my code to an executable jar and run it on my PC external of Eclipse, it still throws an exception.
How do I load such a large image into my application using buffered image without using 1235mb of memory? Is there a trick, like splitting the image into smaller portions like image segmentation?
I found this thread on SO, but it not useful for me; I want to load the image into BufferedImage and then draw it on a Panel using the Graphics class.
You can read and display fragments of the image using ImageReadParam from ImageIO package. Here is a basic example that illustrates how to read a single fragment using ImageReadParam without reading the whole image:
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.*;
public class TestImageChunks {
private static void createAndShowUI() {
try {
URL url = new URL(
"http://duke.kenai.com/wave/.Midsize/Wave.png.png");
Image chunk = readFragment(url.openStream(), new Rectangle(150,
150, 300, 250));
JOptionPane.showMessageDialog(null, new ImageIcon(chunk), "Duke",
JOptionPane.INFORMATION_MESSAGE);
} catch (IOException e) {
JOptionPane.showMessageDialog(null, e.getMessage(), "Failure",
JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
}
public static BufferedImage readFragment(InputStream stream, Rectangle rect)
throws IOException {
ImageInputStream imageStream = ImageIO.createImageInputStream(stream);
ImageReader reader = ImageIO.getImageReaders(imageStream).next();
ImageReadParam param = reader.getDefaultReadParam();
param.setSourceRegion(rect);
reader.setInput(imageStream, true, true);
BufferedImage image = reader.read(0, param);
reader.dispose();
imageStream.close();
return image;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
The result looks like this:
Generally, you'd need to do something like this:
Break the image into manageable size image files and store them on disk with your application.
When displaying a particular part of this image, only the load and display image fragments that overlap your viewport.
As you pan around the image, update the loaded and displayed image fragments appropriately.
Either let the unnecessary image fragments get collected by the GC or load new ones in such a way that they overwrite older ones. (This last argues for identically-sized image fragments that load into pooled memory buffers.)