I know there are similar questions to this one on SO (like this one), however, after reading through the list of "Questions with similar titles", I still feel strongly that this is unique.
I am working with the iText library to generate PDFs from inside a Swing application. iText's Jpeg class requires a URL in its constructor to locate an image/jpg that you want to add to the PDF file.
When I set this URL to the absolute file path of my JPG file, I get a MalformedURLException claiming unknown protocol: c ("c" being the C:\ drive on my local disk).
Is there any hack/circumvention to this, or do I have to host this JPG somewhere and have the URL find it over the net? Here is the code that is failing:
try {
String imageUrl = "C:\Users\MyUser\image.jpg";
Jpeg image = new Jpeg(new URL(imageUrl));
} catch(Exception exc) {
System.out.println(exc.getMessage());
}
Please note: The URL does properly escape the string (thus "\" are converted to "\ \", etc.).
Thanks in advance!
You need to turn the path to the image.jpg file into a file:// URL, like this:
String imageUrl = "file:///C:/Users/MyUser/image.jpg";
Otherwise it interprets the C as the URL protocol.
Try with
String imageUrl = "file:///C:/Users/MyUser/image.jpg";
Try this
try {
String imageUrl = "file:///C:/Users/MyUser/image.jpg";
Jpeg image = new Jpeg(new URL(imageUrl));
} catch(Exception exc) {
System.out.println(exc.getMessage());
}
In my case the issue was that I was having "%" in my file name. Once I changed it, the file was loaded successfully. So I guess special characters are not allowed in file names, at least in windows.
Searching the file with its directory and adding in the image to assign to the ImageView
File file = new File("F:/a.jpg");
Image image = new Image(arquivo.toURI().toString()); //here is magic happens
imageView.setImage(image);
Related
I am trying to get histogram of an image using this code Displaying a histogram of image data. Normally it works fine when input image given by url. But while I give image from local directory
private BufferedImage getImage() {
try {
return ImageIO.read(new URL(
"F:/test.jpg"));
} catch (IOException e) {
e.printStackTrace(System.err);
}
return null;
}
it gives exception,
java.net.MalformedURLException: unknown protocol: f
How to resolve this exception and get Histogram of an image
While the other answers will technically solve your problem, you shouldn't be using a URL for this. There are other signatures for the read function, one which takes a File and one which takes an InputStream instead, so you can use either of the following:
return ImageIO.read(new File("F:/test.jpg"));
// or
return ImageIO.read(new FileInputStream("F:/test.jpg"));
F:/test.jpg is not a valid URL. For files the URL is file://F:/test.jpg
where file is the protocol
The protocol is not valid.
If you need to load a file from the filesystem you need to use the file URI scheme
A file URI takes the form of file://host/path
where host is the fully qualified domain name of the system on which the path is accessible, and path is a hierarchical directory path of the form directory/directory/.../name. If host is omitted, it is taken to be "localhost", the machine from which the URL is being interpreted.
So the url should be:
file://F:/test.jpg
This is a question that has been asked like 100 times on this site, but I have looked at all of them and even though they all were solved, none of the solutions worked for me.
Here's what my code looks like:
public Button1(Client client, String imgName) {
this.client = client;
try {
this.icon = ImageIO.read(this.getClass().getResourceAsStream("/resources/" + imgName));
} catch (IOException e) {
e.printStackTrace();
}
When the code runs it results in the following error:
Exception in thread "main" java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(Unknown Source)
The string imgName is passed to the constructor from a child class and is the name of an image (e.g. image.png). I also have made sure that my resources folder is in the root of the project folder, and is included as a source folder in the eclipse project. I've also made sure that System.getProperty("user.dir") points to the correct location. I have also tried using getResource() instead of getResourceAsStream(), but it still does not work.
Try using this:-
this.icon = ImageIO.read(new FileInputStream("res/test.txt"));
where res folder is present at the same level as your src folder. Also, if you notice, the slash / before the res folder name was removed.
I know this is pretty old, but I just had the same issue.
Check to make sure that your image extensions aren't capital.
In my resources folder for images I had "enemy.PNG", but I was trying to load "enemy.png" which you would think would work but doesn't.
so, just make your extensions aren't capitalized.
I solved mine by changing my code from this
image = ImageIO.read(SpriteSheet.class.getResourceAsStream("res/image.png"));
to this
image = ImageIO.read(SpriteSheet.class.getResourceAsStream("/image.png"));
Hope this helps.
The path passed as the argument to getResourceAsStream() should be relative to the classpath set.
So try changing this
this.icon = ImageIO.read(this.getClass().getResourceAsStream("/resources/" + imgName));
to
this.icon = ImageIO.read(this.getClass().getResourceAsStream("resources/" + imgName));
This may come as a "No, Duh!" to many on this site, but it is always important to point out how literal Java is. Case sensitivity is key, especially if you .jar a file.
If your program works fine with compiling and then running but suddenly is getting this issue when you .jar your files. Make sure to check you Case on your folders / files and your references in your code. (As well as make sure they are in your .jar)
Hope this helps anyone that ends up here looking at the same issue.
Try this:
this.icon = ImageIO.read(this.getClass().getResource("/resources/" + imgName));
Try using the following
this.icon = ImageIO.read(this.getClass().getResourceAsStream("../resources/" + imgName));
Is the resource folder a class folder in eclipse? Right click on the project -> Properties -> Java Build Path -> Libraries -> Add Class Folder... -> (select the res folder) and add it as a class folder.
I was facing this error due to a bug in my code. I was trying to extract (conn.getInputStream()) from a different connection object than what it should have been. I fixed the connection object variable and it started working.
BufferedImage image;
try (InputStream in = new BufferedInputStream(conn.getInputStream())) {
image = ImageIO.read(in);
File file = new File(fullImageFilePath);
synchronized (file.getCanonicalPath().intern()) {
if (!file.exists()) {
ImageIO.write(image, "png", file);
}
}
}
Instead of
this.icon = ImageIO.read(this.getClass().getResourceAsStream("/resources/" + imgName));
Use
this.icon = ImageIO.read(new File("Full Path");
I do not know why the first snippet does not work, but new File() has always worked for me.
You can try this:
image = ImageIO.read(getClass().getResource("/resources/" + imgName));
Try This
private BufferedImage get(String path) throws IOException{
URL url = this.getClass().getClassLoader().getResource(path);
String thing = url.getFile();
return ImageIO.read(new File(thing));
}
I am using some file IO and want to know if there is a method to check if a file is an image?
This works pretty well for me. Hope I could help
import javax.activation.MimetypesFileTypeMap;
import java.io.File;
class Untitled {
public static void main(String[] args) {
String filepath = "/the/file/path/image.jpg";
File f = new File(filepath);
String mimetype= new MimetypesFileTypeMap().getContentType(f);
String type = mimetype.split("/")[0];
if(type.equals("image"))
System.out.println("It's an image");
else
System.out.println("It's NOT an image");
}
}
if( ImageIO.read(*here your input stream*) == null)
*IS NOT IMAGE*
And also there is an answer: How to check a uploaded file whether it is a image or other file?
In Java 7, there is the java.nio.file.Files.probeContentType() method. On Windows, this uses the file extension and the registry (it does not probe the file content). You can then check the second part of the MIME type and check whether it is in the form <X>/image.
You may try something like this:
String pathname="abc\xyz.png"
File file=new File(pathname);
String mimetype = Files.probeContentType(file.toPath());
//mimetype should be something like "image/png"
if (mimetype != null && mimetype.split("/")[0].equals("image")) {
System.out.println("it is an image");
}
You may try something like this:
import javax.activation.MimetypesFileTypeMap;
File myFile;
String mimeType = new MimetypesFileTypeMap().getContentType( myFile ));
// mimeType should now be something like "image/png"
if(mimeType.substring(0,5).equalsIgnoreCase("image")){
// its an image
}
this should work, although it doesn't seem to be the most elegant version.
There are a variety of ways to do this; see other answers and the links to related questions. (The Java 7 approach seems the most attractive to me, because it uses platform specific conventions by default, and you can supply your own scheme for file type determination.)
However, I'd just like to point out that no mechanism is entirely infallible:
Methods that rely on the file suffix will be tricked if the suffix is non-standard or wrong.
Methods that rely on file attributes (e.g. in the file system) will be tricked if the file has an incorrect content type attribute or none at all.
Methods that rely on looking at the file signature can be tricked by binary files which just happen to have the same signature bytes.
Even simply attempting to read the file as an image can be tricked if you are unlucky ... depending on the image format(s) that you try.
Other answers suggest to load full image into memory (ImageIO.read) or to use standard JDK methods (MimetypesFileTypeMap and Files.probeContentType).
First way is not efficient if read image is not required and all you really want is to test if it is an image or not (and maybe to save it's content type to set it in Content-Type response header when this image will be read in the future).
Inbound JDK ways usually just test file extension and not really give you result that you can trust.
The way that works for me is to use Apache Tika library.
private final Tika tika = new Tika();
private MimeType detectImageContentType(InputStream inputStream, String fileExtension) {
Assert.notNull(inputStream, "InputStream must not be null");
String fileName = fileExtension != null ? "image." + fileExtension : "image";
MimeType detectedContentType = MimeType.valueOf(tika.detect(inputStream, fileName));
log.trace("Detected image content type: {}", detectedContentType);
if (!validMimeTypes.contains(detectedContentType)) {
throw new InvalidImageContentTypeException(detectedContentType);
}
return detectedContentType;
}
The type detection is based on the content of the given document stream and the name of the document. Only a limited number of bytes are read from the stream.
I pass fileExtension just as a hint for the Tika. It works without it. But according to documentation it helps to detect better in some cases.
The main advantage of this method compared to ImageIO.read is that Tika doesn't read full file into memory - only first bytes.
The main advantage compared to JDK's MimetypesFileTypeMap and Files.probeContentType is that Tika really reads first bytes of the file while JDK only checks file extension in current implementation.
TLDR
If you plan to do something with read image (like resize/crop/rotate it), then use ImageIO.read from Krystian's answer.
If you just want to check (and maybe store) real Content-Type, then use Tika (this answer).
If you work in the trusted environment and you are 100% sure that file extension is correct, then use Files.probeContentType from prunge's Answer.
Here's my code based on the answer using tika.
private static final Tika TIKA = new Tika();
public boolean isImageMimeType(File src) {
try (FileInputStream fis = new FileInputStream(src)) {
String mime = TIKA.detect(fis, src.getName());
return mime.contains("/")
&& mime.split("/")[0].equalsIgnoreCase("image");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
I create ImageServlet to refer to videos out of my web application scope.
The location of all of my videos are on a intranet location that could be reached from any computer in the intranet:
String path = "\\myip\storage\ogg\VX-276.ogg"
In my application, when I write it as URL - it can't display it!
If I try to open it with chrome it automatically changes it to file://myip/storage/ogg/VX-276.ogg and the file is being displayed.
I tried to do so: file:////odelyay_test64/storage/ogg/
as well but Java converts the string to: file:\myip\storage\ogg\VX-276.ogg which does not exist!
What is the correct way to refer to it?
EDITED
I create a small test:
String path = "file://myip/storage/ogg/VX-276.ogg";
File file = new File(path);
if (file.exists())
System.out.println("exists");
else {
System.out.println("missing" + file.getPath());
}
and I get:
missing file:\myip\storage\ogg\VX-276.ogg
As you can see the slashes are being switched
As per your previous question, you're referencing the resource in a HTML <video> tag. All URLs in the HTML source code must be http:// URLs (or at least be relative to a http:// URL). Most browsers namely refuse to load resources from file:// URLs when the HTML page is itself been requested by http://. You just need to let the URL point to the servlet. If the servlet's doGet() method get hit, then the URL is fine and you should not change it.
Your concrete problem is in the way how you open and read the desired file in the servlet. You need to ensure that the path in File file = new File(path) points to a valid location before you open a FileInputStream on it.
String path = "file://myip/storage/ogg/VX-276.ogg";
File file = new File(path);
// ...
If the servlet code is well written that it doesn't suppress/swallow exceptions and you have read the server logs, then you should have seen an IOException such as FileNotFoundException along with a self-explaining message in the server logs whenever reading the file fails. Go read the server logs.
Update as per the comments, it turns out that you're using Windows and thus file:// on a network disk isn't going to work for Java without mapping it on a drive letter. You need to map //myip on a drive letter first, for example X:.
String path = "X:/storage/ogg/VX-276.ogg";
File file = new File(path);
// ...
in the end I used VFS library of apache and my code looks like this:
public static void main(String[] args) {
FileSystemManager fsManager = null;
String path = "\\\\myip\\storage\\ogg\\VX-276.ogg";
try {
fsManager = VFS.getManager();
FileObject basePath;
basePath = fsManager.resolveFile("file:" + path);
if (basePath.exists())
System.out.println("exists");
else {
System.out.println("missing" + basePath.getURL());
}
} catch (FileSystemException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
In this way, I don't need to create a driver for each user of the system and it allows me not to depend on operation system!
I am having some issue trying to create image using createImage() using j2me. The prog will just hang. I am able to get input from file but I can't createImage. Does anyone have any idea?
if (filenames.exists()) {
InputStream input = filenames.openInputStream();
try { Logger.logEventInfo("READING1: " + imageName);
Image image = Image.createImage(input); //Having problem here...
Try using createImage(String name) version of the method if you are just trying to load the data from an image file. Make sure the image is a PNG, and in the resource (res) folder. The String should be in the format "/filename.png" -- note the leading slash.