java.net.MalformedURLException: unknown protocol: f - java

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

Related

Android Java Get path from URI for an mp4

I'm trying to get a load a mp4 file from the android file browser. However the path from the following code does not work. It throws an exception
Uri currFileURI = data.getData();
String path=currFileURI.getPath();
MediaExtractor extractor = new MediaExtractor();
try {
extractor.setDataSource(path);
} catch( IOException e) {
e.printStackTrace();
return;
}
Data I have:
data = {Intent#9869} "Intent { dat=content://com.android.providers.downloads.documents/document/44 flg=0x1 }"
currFileURI = {Uri$HierarchicalUri#9870} "content://com.android.providers.downloads.documents/document/44"
path = "/document/44"
I see this code in stackoverflow:
How to get the Full file path from URI
This looks like an overkill
I can see the method takes in a file path.
https://developer.android.com/reference/android/media/MediaExtractor#setDataSource(java.lang.String)
So it looks the path from the android file browser is different from what the method wants. I also see that the path from the file browser is different than the file name. Anybody have an insight into what the path should look like?
So it looks the path from the android file browser is different from what the method wants
It is not a filesystem path, because a Uri is not a file.
I can see the method takes in a file path
There are many forms of setDataSource() on MediaExtractor, including one that takes a Uri. Try using that method with your Uri.

How can I fetch image format from a URL in Java?

I have an image that I fetch from a url that has no extension(jpg, gif,png, etc).
I have no problem downloading the image.
BufferedImage image = null;
URL url = new URL(link);
image = ImageIO.read(url);
However, I wanted to know the extension of the file before saving to disk. I tried the following and ImageIO.createImageInputStream(image); is always returning null.
ImageInputStream iis = ImageIO.createImageInputStream(image);
//where image is BufferImage but it is always returning null.
while (imageReaders.hasNext()) {
ImageReader reader = imageReaders.next();
System.out.printf("formatName: %s%n", reader.getFormatName());
return ImageFormatTypes.valueOf(reader.getFormatName());
}
Any advice would be appreciated.
Once you create a java.awt.Image, there is no format. It's not a PNG, it's not a JPEG, it's just a Java Image. So you cannot get the image format from your Image object.
You need to get it from the URL. The most reliable way is to check the URL's content type, then get the extension from the ImageIO provider:
URL url = new URL(link);
URLConnection conn = url.openConnection();
String contentType = conn.getContentType();
String suffix = null;
Iterator<ImageReader> readers =
ImageIO.getImageReadersByMIMEType(contentType);
while (suffix == null && readers.hasNext()) {
ImageReaderSpi provider = readers.next().getOriginatingProvider();
if (provider != null) {
String[] suffixes = provider.getFileSuffixes();
if (suffixes != null) {
suffix = suffixes[0];
}
}
}
You can also save the URL to a temporary file, so you can use Files.probeContentType on it:
URL url = new URL(link);
Path imageFile = Files.createTempFile("image", null);
try (InputStream stream = url.openStream()) {
Files.copy(stream, imageFile, StandardCopyOption.REPLACE_EXISTING);
}
image = ImageIO.read(imageFile.toFile());
String contentType = Files.probeContentType(imageFile);
Files.delete(imageFile);
But you'll still need ImageIO providers to get an extension from a MIME type.
In Java 7+ you can now just use Files.probeContentType(path).
----------
public static String probeContentType(Path path)
throws IOException
Probes the content type of a file.
This method uses the installed FileTypeDetector implementations to
probe the given file to determine its content type. Each file type
detector's probeContentType is invoked, in turn, to probe the file
type. If the file is recognized then the content type is returned. If
the file is not recognized by any of the installed file type detectors
then a system-default file type detector is invoked to guess the
content type.
A given invocation of the Java virtual machine maintains a system-wide
list of file type detectors. Installed file type detectors are loaded
using the service-provider loading facility defined by the
ServiceLoader class. Installed file type detectors are loaded using
the system class loader. If the system class loader cannot be found
then the extension class loader is used; If the extension class loader
cannot be found then the bootstrap class loader is used. File type
detectors are typically installed by placing them in a JAR file on the
application class path or in the extension directory, the JAR file
contains a provider-configuration file named
java.nio.file.spi.FileTypeDetector in the resource directory
META-INF/services, and the file lists one or more fully-qualified
names of concrete subclass of FileTypeDetector that have a zero
argument constructor. If the process of locating or instantiating the
installed file type detectors fails then an unspecified error is
thrown. The ordering that installed providers are located is
implementation specific.
The return value of this method is the string form of the value of a
Multipurpose Internet Mail Extension (MIME) content type as defined by
RFC 2045: Multipurpose Internet Mail Extensions (MIME) Part One:
Format of Internet Message Bodies. The string is guaranteed to be
parsable according to the grammar in the RFC.

Java URL: Unknown Protocol "C"

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

Java URL problem

A webpage contains a link to an executable (i.e. If we click on the link, the browser will download the file on your local machine).
Is there any way to achieve the same functionality with Java?
Thank you
Yes there is.
Here a simple example:
You can have a JSF(Java Server Faces) page, with a supporting backing bean that contains a method annotated with #PostConstruct This means that any action(for example downloading), will occur when the page is created.
There is already a question very similar already, have a look at: Invoke JSF managed bean action on page load
You can use Java's, URL class to download a file, but it requires a little work. You will need to do the following:
Create the URL object point at the file
Call openStream() to get an InputStream
Open the file you want to write to (a FileOutputStream)
Read from the InputStream and write to the file, until there is no more data left to read
Close the input and output streams
It doesn't really matter what type of file you are downloading (the fact that it's an executable file is irrelevant) since the process is the same for any type of file.
Update: It sounds like what you actually want is to plug the URL of a webpage into the Java app, and have the Java app find the link in the page and then download that link. If that is the case, the wording of your question is very unclear, but here are the basic steps I would use:
First, use steps 1 and 2 above to get an InputStream for the page
Use something like TagSoup or jsoup to parse the HTML
Find the <a> element that you want and extract its href attribute to get the URL of the file you need to download (if it's a relative URL instead of absolute, you will need to resolve that URL against the URL of the original page)
Use the steps above to download that URL
Here's a slight shortcut, based on jsoup (which I've never used before, I'm just writing this from snippets stolen from their webpage). I've left out a lot of error checking, but hey, I usually charge for this:
Document doc = Jsoup.connect(pageUrl).get();
Element aElement = doc.getElementsByTag("a").first() // Obviously you may need to refine this
String newUrl = aElement.attr("abs:href"); // This is a piece of jsoup magic that ensures that the destination URL is absolute
// assert newUrl != null
URL fileUrl = new URL(newUrl);
String destPath = fileUrl.getPath();
int lastSlash = destPath.lastIndexOf('/');
if (lastSlash != -1) {
destPath = destPath.substring(lastSlash);
}
// Assert that this is really a valid filename
// Now just download fileUrl and save it to destPath
The proper way to determine what the destination filename should be (unless you hardcode it) is actually to look for the Content-Disposition header, and look for the bit after filename=. In that case, you can't use openStream() on the URL, you will need to use openConnection() instead, to get a URLConnection. Then you can use getInputStream() to get your InputStream and getRequestProperty("Content-Disposition") to get the header to figure out your filename. In case that header is missing or malformed, you should then fall-back to using the method above to determine the destination filename.
You can do this using apache commons IO FileUtils
http://commons.apache.org/io/apidocs/org/apache/commons/io/FileUtils.html#copyURLToFile(java.net.URL, java.io.File)
Edit:
I was able to successfully download a zip file from source forge site (it is not empty), It did some thing like this
import java.io.File;
import java.net.URL;
import org.apache.commons.io.FileUtils;
public class Test
{
public static void main(String args[])
{
try {
URL url = new URL("http://sourceforge.net/projects/gallery/files/gallery3/3.0.2/gallery-3.0.2.zip/download");
FileUtils.copyURLToFile(url, new File("test.zip"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I was able successfully download tomcat.exe too
URL url = new URL("http://archive.apache.org/dist/tomcat/tomcat-6/v6.0.16/bin/apache-tomcat-6.0.16.exe");

Locating a file in a network disk in a Servlet

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!

Categories