Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
ich bin gerade dabei ein JApplet zu programmieren, in dem ich ein Bild hochladen/anzeigen möchte.
Bisher habe ich nur Japplets programmiert, in denen ich mit drawRect() gearbeitet habe, und das hat immer gut funktioniert.
Nur mein jetziges JApplet zum Anzeigen eines Bildes von meiner Festplatte (Das Bild liegt auch im selben Verzeichnis wie mein Code und ist eine png-Datei) bleibt weiss ohne das Bild.
Mein Code sieht wie folgt aus:
Java:
import java.applet.Applet;
import java.awt.*;
public class FigurenApplet extends Applet {
private final int GROESSE = image.getHeight();
private final int RAND = 50;
public void init() {
setSize(500, 500);
}
public void paint(Graphics g) {
Image image;
image = getImage(getCodeBase(), "Bild.png");
g.drawImage(image,0,0,this);
}
}
Es wär echt super, wenn mir jemand sagen könnte, woran das liegen kann.
Ein großer Fehler ist es, die Bild-Datei in der paint()-Methode zu laden.
Dieser Vorgang kann u.U. etwas dauern, das Bild wird möglicherweise nicht gezeichnet, weil es noch nicht vollständig geladen ist. Außerdem, wird das Bild jedes Mal geladen, wenn etwas im Applet (neu) gezeichnet werden soll - eine Performance-Falle also.
Lese das Bild in der init()-Methode. In JApplets benutzt du zum Einlesen von Bildern am Besten ImageIO. In Applets benutzt du dafür den MediaTracker.
Ok, dann mach ich das mit dem Applet SCHREIBEN mal ganz konkret:
Wir sollten vor 3 Wochen ein Programm schreiben, das das Minimum und Maximum eines 2-dim. Feldes berechnet, und dann ein weiteres Programm, das mithilfe des ersten Programms ein gegebenes Bild einmal in Graustufen und daneben einmal als "Kantenbild" anzeigt.
Mein Code lässt sich fehlerfrei übersetzen und ich hab auch volle Punktzahl drauf bekommen.
Aber: Das JApplet tut nicht das, was es soll.
Es wird nur für weniger als eine Sekunde angezeigt, und es zeigt auch nicht die zwei Bilder an, die es eigentlich anzeigen sollte.
Im Folgenden steht der Code.
Ich kann keinen Fehler im Code finden, vielleicht kann mir jemand sagen, was ich falsch mache ???:L
Das hier ist mein Programm zur Berechnung von Minimum/Maximum, welches tut was es soll:
Java:
public class MinMax2D {
public static int min2D(int[][] feld) {
int min = feld[0][0];
for (int i = 0; i < feld.length; i++) {
for (int j = 0; j < feld[i].length; j++) {
if (feld[i][j] < min) {
min = feld[i][j];
}
}
}
return min;
}
public static int max2D(int[][] feld) {
int max = feld[0][0];
for (int i = 0; i < feld.length; i++) {
for (int j = 0; j < feld[i].length; j++) {
if (feld[i][j] > max) {
max = feld[i][j];
}
}
}
return max;
}
public static void main(String[] args) {
int[][] feld = { {1,2,3},{4,2,-3},{3,6,3}};
System.out.println(min2D(feld));
System.out.println(max2D(feld));
}
}
Das hier ist der Code der Klasse GdiImage, die es zum Runterladen gab, und die wir verwenden sollten:
Java:
package uebung;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
public class GdiImage {
private BufferedImage bimg = null;
public GdiImage(final int width, final int height) {
bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
bimg.setRGB(x, y, Color.BLACK.getRGB());
}
}
}
public GdiImage(final String filename) {
this.load(filename);
}
public GdiImage(final URL url) {
this.load(url);
}
public void load(final String filename) {
try {
load(new File(filename).toURI().toURL());
} catch (MalformedURLException e) {
System.err.println(e.toString());
System.exit(1);
}
}
public void load(final URL url) {
// load image
try {
bimg = ImageIO.read(url);
} catch (IOException e) {
System.err.println(e.toString());
System.exit(1);
}
}
public void save(final String filename, final String format) {
try {
ImageIO.write(bimg, format, new File(filename));
} catch (IOException e) {
System.err.println(e.toString());
System.exit(1);
}
}
public int getWidth() {
return bimg.getWidth();
}
public int getHeight() {
return bimg.getHeight();
}
public int[][] getPixels() {
int width = bimg.getWidth();
int height = bimg.getHeight();
// copy into 2-dimensional array
int[] data = bimg.getRGB(0, 0, width, height, null, 0, width);
int[][] pixels = new int[height][width];
for (int y = 0; y < height; y++) {
System.arraycopy(data, y * width, pixels[y], 0, width);
}
return pixels;
}
public void setPixels(final int[][] pixels) {
int width = bimg.getWidth();
int height = bimg.getHeight();
if ((height != pixels.length) || (width != pixels[0].length)) {
System.err.println("GdiImage.setPixels(): size of both images differ!");
return;
}
int[] data = new int[width * height];
for (int y = 0; y < height; y++) {
assert pixels[y].length == width : "Evil GDIler is doing nasty things.";
System.arraycopy(pixels[y], 0, data, y * width, width);
}
bimg.setRGB(0, 0, width, height, data, 0, width);
}
public BufferedImage getImage() {
return bimg;
}
public void draw(final Graphics g, final int x, final int y) {
g.drawImage(bimg, x, y, null);
}
}
Und das hier ist jetzt der Code für das JApplet mit den zwei Bildern, in dem der Wurm stecken muss, (falls ich alle Dateien im richtigen Verzeichnis abgelegt habe; und zwar liegen alle 3 Klassen, sowie das Bild, das zweimal hochgeladen und verändert dargestellt werden soll, im selben Ordner) :
Java:
import java.awt.Graphics;
import javax.swing.JApplet;
import uebung.GdiImage;
public class SobelApplet extends JApplet {
private GdiImage image1;
private GdiImage image2;
private final int RAND = 10;
public void init() {
/* Bilder laden */
image1 = new GdiImage("lena.jpg");
image2 = new GdiImage("lena.jpg");
/* Applet auf richtige Groesse setzen */
int sizeX = 3 * RAND + 2 * image1.getWidth();
int sizeY = 2 * RAND + image1.getHeight();
setSize(sizeX, sizeY);
/* Bild 1 nach Graustufen umwandeln */
int[][] pixels = wandleBildNachGraustufen(image1.getPixels());
image1.setPixels(pixels);
int[][] sobelX = { { 1, 0, -1 }, { 2, 0, -2 }, { 1, 0, -1 } };
int[][] sobelY = { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } };
/* Umwandeln */
int[][] pixelsX = wendeMaskeAn(pixels, sobelX);
int[][] pixelsY = wendeMaskeAn(pixels, sobelY);
int[][] gefiltertesBild = new int[pixels.length][pixels[0].length];
/* Helligkeitswert verrechnen */
for (int i = 0; i < pixelsX.length; i++) {
for (int j = 0; j < pixelsX[0].length; j++) {
int wert = (int) Math.sqrt(Math.pow(pixelsX[i][j], 2)
+ Math.pow(pixelsY[i][j], 2));
gefiltertesBild[i][j] = wert;
}
}
/* min/max bestimmen */
int min = MinMax2D.min2D(gefiltertesBild);
int max = MinMax2D.max2D(gefiltertesBild);
/* Bild normalisieren und invertieren */
for (int i = 0; i < pixelsX.length; i++) {
for (int j = 0; j < pixelsX[0].length; j++) {
int grau = 255 - (gefiltertesBild[i][j] - min) * 255 / (max - min);
gefiltertesBild[i][j] = (grau << 16) + (grau << 8) + grau;
}
}
image2.setPixels(gefiltertesBild);
}
public void paint(Graphics g) {
g.drawImage(image1.getImage(), RAND, RAND, null);
g.drawImage(image2.getImage(), RAND + image1.getWidth() + RAND, RAND, null);
}
public int[][] wandleBildNachGraustufen(int[][] pixels) {
for (int i = 0; i < pixels.length; i++) {
for (int j = 0; j < pixels[0].length; j++) {
int rgb = pixels[i][j];
int r = (rgb >> 16) & 255;
int g = (rgb >> 8) & 255;
int b = rgb & 255;
int grau = (77 * r + 151 * g + 28 * b) / 256;
rgb = (grau << 16) + (grau << 8) + grau;
pixels[i][j] = rgb;
}
}
return pixels;
}
public int[][] wendeMaskeAn(int[][] pixels, int[][] maske) {
int[][] pixelsNeu = new int[pixels.length][pixels[0].length];
int offset = maske.length / 2;
for (int i = offset; i < pixelsNeu.length - offset; i++) {
for (int j = offset; j < pixelsNeu[i].length - offset; j++) {
int sum = 0;
for (int k = 0; k < maske.length; k++) {
for (int l = 0; l < maske.length; l++) {
sum += (pixels[i + k - offset][j + l - offset] & 255) * maske[k][l];
}
}
pixelsNeu[i][j] = sum;
}
}
return pixelsNeu;
}
}
Es wäre mir wirklich wichtig herauszufinden, wie es richtig geht, denn es ist überhaupt nicht zufriedenstellend, wenn man nach viel Arbeit immer kurz davor bleibt, sich auch ansehen zu können, was man tolles gemacht hat
ich hab mir jetzt Java 6 runtergeladen, weil ich gedacht hab, dass es vielleicht daran liegt, dass ich bis jetzt mit Java 5 gearbeitet hab.
Wenn ich das JApplet ausführe, erscheint auf der Konsole folgendes:
javax.imageio.IIOException: Can't get input stream from URL!
Aber ich verstehe nicht, was ich ändern muss. Denn:
Im Code der Klasse GdiImage benutze ich doch den GdiImage-Konstruktor aus Zeile 23, und nicht den aus Zeile 27.
Oder liegt das daran, dass die load-Methode aus Zeile 31 letztendlich auch über eine URL läuft?
Mein Bild liegt aber im selben Ordner wie die Code-Datei.
Hat jemand eine Idee, was falsch sein könnte? ???:L
Ich übergebe der Methode load() einen String mit dem Namen der Datei, die ich hochladen möchte, da ich ja dem GdiImage-Konstruktor als Argument einen String übergeben hab.
In Applets muss man fast immer über die getCodeBase()/getDocumentBase() den Pfad aufbauen.
Sobald File im Spiel ist, werden in unsignierten Applets AccessControlExceptions geworfen.
Poste bitte mal die gesamte Exception.
ich hab den Fehler gefunden.
Das Bild, das ich hochladen wollte, lag in einem Ordner des Binary-Ordners,
und ich hab nur den Dateinamen, anstatt Ordner/Dateiname angegeben!