I am trying to load an image from a URL and this was very easy and works great. However, if the image doesnt exist I want it to default to a local image. The problem I am having is that it doesnt throw any exceptions. Instead it will just not display anything. I'm assuming I have to validate the URL some how, but I want to also be sure that its an image and not a webpage/script...etc
Here is my basic test code. This works:
public class DownloadImage extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
VBox root = new VBox();
String imageSource = "https://www.wbkidsgo.com/Portals/1/Content/Hero/HeroBugsCarrot/Source/Default/WB_LT_HeroImage_Bugs_v1.png";
ImageView imageView = new ImageView(new Image(imageSource));
root.getChildren().add(imageView);
primaryStage.setScene(new Scene(root, 1000, 1000));
primaryStage.show();
}
}
But if I load a bad URL i.e. (two s's in Portals):
String imageSource = "https://www.wbkidsgo.com/Portalss/1/Content/Hero/HeroBugsCarrot/Source/Default/WB_LT_HeroImage_Bugs_v1.png";
It will just be blank. I thought about creating an HTTP client and sending a request prior to creating the image, but generating the HTTP client takes a few seconds and I will be loading upwards of 300 or so images. I guess I can have one http client, and make one request for each image and check the response datatype to see if its an image, but is there a better way?
You can use the errorProperty and exceptionProperty to check the error status of the image:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.image.Image;
import javafx.stage.Stage;
public class ImageTest extends Application {
public static void main(String[] args) {
launch(args) ;
}
#Override
public void start(Stage primaryStage) {
String[] urls = new String[]{
"https://www.wbkidsgo.com/Portals/1/Content/Hero/HeroBugsCarrot/Source/Default/WB_LT_HeroImage_Bugs_v1.png",
"https://www.wbkidsgo.com/Portalss/1/Content/Hero/HeroBugsCarrot/Source/Default/WB_LT_HeroImage_Bugs_v1.png"
} ;
for (String url : urls) {
Image image = new Image(url);
if (image.isError()) {
System.out.println("Error loading image from "+url);
// if you need more details
// image.getException().printStackTrace();
} else {
System.out.println("Successfully loaded image from " + url);
}
}
Platform.exit();
}
}
Which gives the following output:
Successfully loaded image from https://www.wbkidsgo.com/Portals/1/Content/Hero/HeroBugsCarrot/Source/Default/WB_LT_HeroImage_Bugs_v1.png
Error loading image from https://www.wbkidsgo.com/Portalss/1/Content/Hero/HeroBugsCarrot/Source/Default/WB_LT_HeroImage_Bugs_v1.png
You can use the ImageView.setImage() method to change the image. I recommend initializing the ImageView using your default image in the form of a BufferedImage, then setting it later with your actual image. You can load this from your filesystem or classpath using ImageIO.
As for the actual image, I would also use ImageIO to load the url as a BufferedImage. This throws an IOException, so if it errors or does not link to a supported image type, nothing will happen.
If you know much about threads and concurrency, I would load the image on another thread so it doesn't freeze your main thread.
Related
I am in the process of creating a small video editor and currently trying to get video files to display in the preview window. To do that, I want to get a frame of a video at a specific position using JavaCVs FFmpegFrameGrabber.
I have figured out a way of doing this, by setting the frameNumber variable of the grabber to the needed frame. However, this results in only the first frame of the file being displayed and some information about the file being printed out repeatedly (tell me if you need to see it, it's just kind of long and messy) alongside the error:
[swscaler # 000001927a7d3000] bad src image pointers
This is my frame grabbing class:
public class Video {
private FFmpegFrameGrabber grabber;
private final static Java2DFrameConverter converter = new Java2DFrameConverter();
public Video(File file) {
this.grabber = new FFmpegFrameGrabber(file);
try {
this.grabber.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public BufferedImage grabFrame(int framePos) throws Exception {
BufferedImage frame;
grabber.grabImage(); // Without this done before, the image is just black
grabber.setFrameNumber(framePos);
frame = converter.convert(grabber.grabImage());
return frame;
}
}
I am very thankful for your answers!
I'm making java application with javaFx ui in kind of tiny machine. I wanted to show loading page, and load data files during the progress indicator going on.
I know it could work well if I added Platform.runlater on the code loading fxml file and controller, but it's weird for me to use Platform.runlater on javaFx main app thread. I checked threads' name but they were same. Also it works if it run separately using annotation.
Why do i need to use Platform.runlater ?
If I don't add that, loading image turns white screen and skip image, and just show menu view.
//Process
//1. Set loading page image
//2. Load data files
//3. Load next page(menu)
public void loadHomeMenuPage() {
setLoadingImage();
execLoadingData();
execLoadingView(this);
}
private void setLoadingImage() {
System.out.println("Load -> " + Thread.currentThread());
File file = new File("Resources/images/load.png");
InputStream is;
try
{
is = new FileInputStream(file);
this.logoImageView.setImage(new Image(is));
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
private void execLoadingData() {
// load openCv files
new LoadOpenCV();
// load protocol files
new ProtocolLoader().load();
// load language pack here
}
private void execLoadingView(IController loadController) {
//Load homeMenu after loading all data
//Platform.runLater(() -> {
System.out.println(Thread.currentThread());
IController controller = (IController) FxmlUtils.LOAD
.fxmlPath(PathFxml.ABS_PATH_HOME_MENU_VIEW)
.pane("BorderPane")
.set2BaseBorderPane(this.baseBorderPane, "center")
.exec();
controller.setBaseBorderPane(this.baseBorderPane);
//});
}
I need help.
I need display jpg image from url.
Desktop version work fine
byte[] imgBytes
new Pixmap(imgBytes, 0, imgBytes.length)
But it is not work in GWT project.
I try this solution "Tainted canvases may not be loaded" Cross domain issue with WebGL textures
public void downloadPixmap(final String url, final DownloadPixmapResponse response) {
final RootPanel root = RootPanel.get("embed-html");
final Image img = new Image(url);
img.getElement().setAttribute("crossOrigin", "anonymous");
img.addLoadHandler(new LoadHandler() {
#Override
public void onLoad(LoadEvent event) {
HtmlLauncher.application.getPreloader().images.put(url, ImageElement.as(img.getElement()));
response.downloadComplete(new Pixmap(Gdx.files.internal(url)));
root.remove(img);
}
});
root.add(img);
}
interface DownloadPixmapResponse {
void downloadComplete(Pixmap pixmap);
void downloadFailed(Throwable e);
}
but it is work only in Chrome browser. It is not work in Mozilla Firefox.
Help me please
Problem was in url. Some url do not have header
Access-Control-Allow-Origin *
That is why images do not display. I fix this using nginx.
Here link to my settings, my problems and ansvers
https://serverfault.com/questions/816080/nginx-proxy-pass-regexp-to-another-domain
Im Trying to load my images on to Java but when running the code nothing appears inside my JFrame.
The way im doing it is calling my Image function from my main:
import java.awt.*; // Graphics stuff from the AWT library, here: Image
import java.io.File; // File I/O functionality (for loading an image)
import javax.swing.ImageIcon; // All images are used as "icons"
public class GameImage
{
public static Image loadImage(String imagePathName) {
// All images are loades as "icons"
ImageIcon i = null;
// Try to load the image
File f = new File(imagePathName);
if(f.exists()) { // Success. Assign the image to the "icon"
i = new ImageIcon(imagePathName);
}
else { // Oops! Something is wrong.
System.out.println("\nCould not find this image: "+imagePathName+"\nAre file name and/or path to the file correct?");
System.exit(0);
}
// Done. Either return the image or "null"
return i.getImage();
} // End of loadImages method
}
And then calling it here:
GI_Background = GameImage.loadImage("Images//background.jpg");
GI_DuskyDolphin = GameImage.loadImage("Images//DuskyDolphin.jpg");
If this is not enough information I'll gladly supply the rest of the code :)
Thanks
If the image is part of the application, do not use a File but use the java resource mechanism.
URL imageUrl = getClass().getResource("/Images/background.jpg");
return new ImageIcon(imageURL).getImage();
The resource URL will return null when not found.
If the application is packed in a .jar, you can open that with 7zip/WinZip or so, and check the path. It must be case-sensitive, and using / (not backslash).
I'm not quite sure what you try to achieve...
to load an image with a method, this will be enough:
private Image loadImage(String fileName){
return (new ImageIcon(fileName)).getImage();
}
Afterwards, i would create a JLabel with the Image as background;
ImageIcon image = getImage( filename );
JLabel imageLabel = new JLabel( image );
imageLabel.setSize( image.getIconHeight, image.getIconWidth );
JFrame frame = new JFrame();
frame.add( imageLabel );
Try this and feel free to aks again if i does not work for you, or thats not want you want :)
I know this is a repeat question.
check original one here or here.
So my code is just the copy paste :
import javafx.scene.media.*;
class Gui {
public static void main(String[] args) {
try{
Media hit = new Media("skin.mp3");
MediaPlayer mediaPlayer = new MediaPlayer(hit);
mediaPlayer.play();
}catch(Exception e){
e.printStackTrace();
}
}
}
The exception which i'm getting is :
java.lang.IllegalArgumentException: uri.getScheme() == null!
at com.sun.media.jfxmedia.locator.Locator.<init>(Locator.java:217)
at javafx.scene.media.Media.<init>(Media.java:364)
at Gui.main(gui.java:6)
I'm compiling & running it correctly i.e. by including the jfxrt.jar file in classpath
Note: I'm just using notepad instead of any IDE.
So can anyone tell me the reason of IllegalArgumentException
Thankx
UPDATE : By using file://e:/skin.mp3 it worked fine but left me with another exception :
MediaException: MEDIA_INACCESSIBLE : e
at javafx.scene.media.Media.<init>(Unknown Source)
at Gui.main(gui.java:6)
So if you can put some light on this exception.
By the way i've checked the song, its not corrupt because it is playing nicely in vlc.
From the JavaFX API docs
The supplied URI must conform to RFC-2396 as required by java.net.URI.
Only HTTP, FILE, and JAR URIs are supported.
So, I suspect from reading the docs, you need to supply a URI path.
Something like file://path/to/file/skin.mp3 will probably work.
There are a few problems with the code in this question.
The class needs to be public.
JavaFX 2 applications need to extend the Application class.
JavaFX 2 applications should define a start method.
The locator for the media being created should be a full URI as noted by MadProgrammer.
Even though the question has a javafx-2 tag, I wonder if it is written for JavaFX 1.x JavaFX Script (which is now an unsupported programming language and incompatible with JavaFX 2). If so, I'd recommend coding in Java and using JavaFX 2.x for this rather than JavaFX Script.
On Windows a file representation of an absolute locator of a URI has three slashes after the file protocol. For example, the following is valid:
file:///C:/Users/Public/Music/skin.mp3
For some reason, a single slash will also work (I guess internally Java will interpolate the extra // for the protocol specifier on files or perhaps there is something I don't understand in the URL specification which means that you don't need a // after the protocol).
file:/C:/Users/Public/Music/skin.mp3
One way to check the file uri for something is valid to ask if the file uri exists
System.out.println("File " + filename + " exists? " + new File(filename).exists());
After you know your file uri is valid, you can convert it to a string using.
file.toURI().toURL().toExternalForm()
Here is a short sample program for playing some audio in JavaFX using a MediaPlayer with a little bit of error handling, so that it is easier to understand if something goes wrong.
import java.io.File;
import java.net.MalformedURLException;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.media.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/** plays an audio in JavaFX 2.x */
public class SimpleAudioPlayer extends Application {
public static void main(String[] args) { launch(args); }
#Override public void start(Stage stage) throws MalformedURLException {
final Label status = new Label("Init");
MediaPlayer mediaPlayer = createMediaPlayer(
"C:/Users/Public/Music/Sample Music/Future Islands - Before the Bridge.mp3",
status
);
StackPane layout = new StackPane();
layout.getChildren().addAll(status);
stage.setScene(new Scene(layout, 600, 100, Color.CORNSILK));
stage.show();
if (mediaPlayer != null) {
mediaPlayer.play();
}
}
/**
* creates a media player using a file from the given filename path
* and tracks the status of playing the file via the status label
*/
private MediaPlayer createMediaPlayer(final String filename, final Label status) throws MalformedURLException {
File file = new File(filename);
if (!file.exists()) {
status.setText("File does not exist: " + filename);
}
final String mediaLocation = file.toURI().toURL().toExternalForm();
Media media = new Media(mediaLocation);
MediaPlayer mediaPlayer = new MediaPlayer(media);
mediaPlayer.setOnError(new Runnable() {
#Override public void run() {
status.setText("Error");
}
});
mediaPlayer.setOnPlaying(new Runnable() {
#Override public void run() {
status.setText("Playing: " + mediaLocation);
}
});
mediaPlayer.setOnEndOfMedia(new Runnable() {
#Override public void run() {
status.setText("Done");
}
});
return mediaPlayer;
}
}
Here is a link to an additional example of a JavaFX 2.x media player which plays all of the mp3 files in a given directory sequentially.