Verkleinerung von Bildern

Status
Nicht offen für weitere Antworten.

thesecretboy

Mitglied
Hallo zusammen,

wir haben in unserer Webseite einen Upload-Button für Bilder integriert. D.h. der User wählt lokal sein Bild aus und kann es dann über einen Upload-Button "hochladen". Nun haben wir User, die uns Ihre Bilder direkt aus der Kamera mit einer großen Auflösung schicken. Daher müssen die Bilder weiter verkleinert werden. Da dies bei uns ewig dauert und das Bild qualitativ sehr leidet, hierzu 2 Fragen:

1.)
In Irfan-View gibt es zum Besipiel ein paar tolle Möglichkeiten, ein Bild zu verkleinern, so dass es danach richtig gut aussieht. Gibt es in Java eine schnelle Möglichkeit, die ein Bild z. B. unter Verwendung des "Hermite"-Filters (weil der laut Irfan-View der schnellste ist) zu verkleinern?


2.)
Mal ganz allgemein gefragt: Gibt es unter Java eine Möglichkeit, Bilder zu verkleinern, so daß die Geschwindigkeit auch bei großen Bildern ab ca. 300k nicht wesentlich langsamer ist als mit Graphics2D.drawImage unter Verwendung von RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR.

Danke für Euere Antworten
 

Marco13

Top Contributor
thesecretboy hat gesagt.:
Mal ganz allgemein gefragt: Gibt es unter Java eine Möglichkeit, Bilder zu verkleinern, so daß die Geschwindigkeit auch bei großen Bildern ab ca. 300k nicht wesentlich langsamer ist als mit Graphics2D.drawImage unter Verwendung von RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR.

Ja, mit Graphics2D.drawImage unter Verwendung von RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR. :wink: Du könntest ja einfach ein BufferedImage mit der gewünschten Größe erstellen, dir davon dann das Graphics2D holen, und DORT reinzeichnen. Hab's jetzt nicht getestet, aber in Anlehnung an deine Aussage müßte es schneller sein...
 

thesecretboy

Mitglied
Hmmm... aus meinem Beitrag ging leider offensichtlich nicht deutlich hervor, wo genau unser Problem liegt.

Der bisherige Code lautet im Wesentlichen:

Code:
// outWidth, outHeight = Zielbreite und -höhe // inImage = das Originalbild, welches verkleinert werden soll BufferedImage outImage = new BufferedImage(outWidth,outHeight,BufferedImage.TYPE_INT_RGB);
Graphics2D g2D = outImage.createGraphics(); g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_I
NTERPOLATION_NEAREST_NEIGHBOR);
g2D.drawImage(inImage,0,0,outWidth,outHeight,null);

Die Qualität des verkleinerten Bildes läßt dabei sehr zu wünschen übrig, andererseits steigt der Zeitaufwand für große Bilder (ab ca. 200k) bei Verwendung von RenderingHints.VALUE_INTERPOLATION_BILINEAR oder gar RenderingHints.VALUE_INTERPOLATION_BICUBIC sehr stark an.

RenderingHints.VALUE_ANTIALIAS_ON scheint überhaupt keine Auswirkung zu haben.

Gibt es also eine Möglichkeit, in Java ein Bild in besserer Qualität zu verkleinern, ohne dabei wesentlich langsamer zu werden als mit obigem Code?
 
G

Gast

Gast
klar, umwander das eingebaute graphics system, schreib dir deine eigene methode, die direkt auf dem bild arbeitet und optimier sie anständig ;)
 

Marco13

Top Contributor
Ach so ... ja, es gibt bei Bildern auch eine Methode getScaledInstance - VIELLEICHT ist die schneller oder besser (ich hatte gedacht, dass du die verwendest, und sie dir zu langsam wäre), Der Methode kann man verschiedene Parameter mitgeben, die die Qualität des Ergebnisses beeinflussen...
 

thesecretboy

Mitglied
Ich habe gerade erfahren, dass wir diese Methode bereits getestet haben. Sie ist leider auch nicht schneller. Weiss jemand, ob es vielleicht am Markt fertige Produkte gibt, die das hergeben, was wir benötigen? Auch kommerzielle sind Willkommen.
 

EgonOlsen

Bekanntes Mitglied
Wie langsam ist eigentlich das "Langsam", von dem wir hier sprechen? Und was macht ihr mit den skalierten Bildern? Zeigt ihr die dem User direkt wieder an?
 

thesecretboy

Mitglied
Nachdem das Bild hochgeladen wird, soll es gleich (bei guter Qualität) heruntergerechnet werden auf 1024*768, da wir einige User haben, die uns Bilder direkt aus der Digicam hochladen und diese eine entsprechende Auflösung haben. Hier haben wir nun das Problem, dass die verwendete Routine bei guter Auflösung teilweise bis zu 8 Minuten pro Bild benötigt. Und das ist in Anbetracht, dass das ganze auf einem aktuellen Doppelprozessor-Server mit 4GB Ram passiert einfach zu lange.
 

Hilefoks

Bekanntes Mitglied
Moin,

JMagick könnte helfen. JMagick ist eine Schnittstelle zu ImageMagick, eine sehr bekannte freie Software zur Erstellung und Bearbeitung von Rastergrafiken.

JMagick selbst habe ich noch nicht benutzt. Die Geschwindigkeit von ImageMagick war für meine Zwecke bisher aber immer ausreichend.

MfG,
Hilefoks
 

EgonOlsen

Bekanntes Mitglied
thesecretboy hat gesagt.:
Hier haben wir nun das Problem, dass die verwendete Routine bei guter Auflösung teilweise bis zu 8 Minuten pro Bild benötigt. Und das ist in Anbetracht, dass das ganze auf einem aktuellen Doppelprozessor-Server mit 4GB Ram passiert einfach zu lange.
Sehr übel...wollte das nicht so recht glauben und habe es selber mal ausprobiert (mit einem 10MP-Bild auf einer P4-2.4Ghz-Gurke). Ich habe den Versuch abgebrochen, so lange hat es gedauert. Das ist nicht sinnvoll benutzbar. Ich schließe mich daher dem obigen Poster an: Baut was eigenes!
 

EgonOlsen

Bekanntes Mitglied
Ein Beispiel für was eigenes (die Interpolationsfunktion ist vorhanden, aber fragwürdig...ist einfach ein geistiger Auswurf von 5min und deshalb sicher nicht so toll). PixelGrabber sind auf großen Bildern übrigens auch zu vermeiden. Sie sind unglaublich langsam. Naja, egal. Also:

Code:
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.imageio.stream.*;

import java.awt.*;
import java.awt.image.*;

public class ScaleTest {
  public static void main(String[] args) throws Exception {
    System.out.println("Lesen...");
    Image img = ImageIO.read(new File("test.jpg"));
    System.out.println("Machen...");
    Image dest = downsample(img,1024,768);
    System.out.println("Schreiben...");
    writeImage(dest,"rescaled.jpg");
  }

  public static Image downsample(Image img,int twidth,int theight) throws Exception {
    int width = img.getWidth(null);
    int height = img.getHeight(null);

    // Pixel zugreifbar machen...PixelGrabber ist viel zu langsam
    BufferedImage sdest = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
    sdest.getGraphics().drawImage(img,0,0,null);
    DataBufferInt data = (DataBufferInt) (sdest.getRaster().getDataBuffer());
    int[] pixels = data.getData();

    // Zielbild erzeugen
    BufferedImage dest = new BufferedImage(twidth,theight,BufferedImage.TYPE_INT_RGB);
    DataBufferInt tdata = (DataBufferInt) (dest.getRaster().getDataBuffer());
    int[] dPixels = tdata.getData();

    float idx = (float) width / (float) twidth;
    float idy = (float) height / (float) theight;

    float px = 0;
    float py = 0;

    for (int y = 0;y < theight;y++) {
      int yp = y * twidth;
      for (int x = 0;x < twidth;x++) {
        int colr = 0;
        int colg = 0;
        int colb = 0;
        int adds = 0;

        // Ziemlich maue Interpolation anwenden...
        for (int ix = 0;ix < idx;ix++) {
          for (int iy = 0;iy < idy;iy++) {
            int pos = ((int) (px)) + ix + ((int) (py) + iy) * width;
            if (pos >= pixels.length) {
              pos = pixels.length - 1;
            }
            int pix = pixels[pos];
            int r = (pix & 0x00ff0000) >> 16;
            int g = (pix & 0x0000ff00) >> 8;
            int b = pix & 0x000000ff;
            colr += r;
            colg += g;
            colb += b;
            adds++;
          }
        }

        // Ergebnispixel schreiben...
        dPixels[yp + x] = (colr / adds) << 16 | (colg / adds) << 8 | (colb / adds);
        px += idx;
        if (px >= width) {
          px = 0;
          py += idy;
        }
      }
    }
    return dest;
  }

  // Als JPEG schreiben
  public static void writeImage(Image image,String path) throws Exception {
    if (image instanceof RenderedImage) {
      Iterator itty = ImageIO.getImageWritersBySuffix("jpeg");
      if (itty.hasNext()) {
        ImageWriter iw = (ImageWriter) itty.next();

        ImageWriteParam iwp = iw.getDefaultWriteParam();
        iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        iwp.setCompressionQuality(0.95f);

        ImageOutputStream ios = ImageIO.createImageOutputStream(new File(path));

        iw.setOutput(ios);
        iw.write(null,new IIOImage((RenderedImage) image,null,null),iwp);
        ios.close();
      }
      else {
        throw new RuntimeException("Keinen Writer gefunden!");
      }
    }
    else {
      throw new RuntimeException("Ja, nee...och...!");
    }
  }
}
 

uwe75-1

Mitglied
Hallo,
ich möchte auch über den Webbrowser mit einem java Applet Bilder auf meine Homepage hochladen, allerdings möchte ich diese 1:1 hochladen, d.h. keine Kompriemierung etc. Das Applet soll absolut keine Veränderung an der datei vornehmen - einfach nur Kopieren. Ich benutze dafür unter anderem die Klasse ImageIO. Das Hochladen funktioniert einwandfrei, aber wenn ich die Eigenschaften der hochgeladenen datei dann vergleiche, dann ist die dpi Anzahl von der Kopie 96 dpi und das Original hat eine andere DPI Anzahl. Wie kann das passieren? Wenn Ihr den Quellcode benötigt, dann sende ich Ihn gern, allerdings ist der 5 Seiten lang - deshalb versuche cih den erstmal zu vermeiden!

Vielen Dank schon mal im Voraus für eure Hilfe
 

uwe75-1

Mitglied
Ja das könnte ich schon machen, aber andere Benutzer sollen ebenfalls ihre dateien auf meinem webspace zur verfügung stellen können - dann funktioniert das kopieren nichtmehr, denn die kennen ja meine zugangsdaten zum webspace nicht - das sollen sie auch nicht. Oder was meinst du genau mit "kopieren"? Gibt es da in java einem simplen copy-befehl?

Vielen dank für die schnelle antwort
 

uwe75-1

Mitglied
Hallo,

also mit Java stecke ich noch voll in den Kinderschuhen und habe nun versucht, über Input/Outstream in Büchern und im Internet mehr zu erfahren, aber irgendwie komme ich da nicht weiter. Könntest Du mir bitte noch ein paar mehr Tips geben, wie ich mein 1:1 Upload Problem lösen kann?

Vielen dank schon mal für deine Hilfe
 

uwe75-1

Mitglied
die bilder werden mit ImageIO.read() in ein BufferedImage hochgeladen und dann als ByteArrayOutputStream an ein PHP Skript übergeben mit URLConnection usw.. kann Dir den Quellcode gern mal schicken aber das sind 5 Seiten!
 

uwe75-1

Mitglied
Sorry, wenn ich wieder nerven muß - hab es bis jetzt nur hinbekommen, daß ein File im selben lokalen Verzeichnis auf meinem Rechner mit anderen Namen gespeichert wird. Wie kann ich nun den FileOutPutStream über URLConnection an mein PHP-Skript übergeben.
ich habe echt keine Idee mehr, warum die Übergabe ständig scheitert.
Vielen Vielen Dank
 

Loep

Aktives Mitglied
Hi,

ich habe den Quellcode von EgonOlsen verwendet um Bilder zu verkleinern und bekomme folgende Exception:

Code:
Lesen...
Exception in thread "main" javax.imageio.IIOException: Unsupported Image Type
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:940)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:915)
	at javax.imageio.ImageIO.read(ImageIO.java:1422)
	at javax.imageio.ImageIO.read(ImageIO.java:1282)
	at ImageResizer.main(ImageResizer.java:12)

Gibt es eine Methode, die nicht so empfindlich ist, wenn mal irgendwelche Metadaten falsch sind?
Es ist ein Farbbild und der Konqueror meint auch das Farbschema sei S/W.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Anzeigemöglichkeit von Bildern in JavaFX mit Hilfe von MongoDB GridFS Allgemeine Java-Themen 0
R Optimierung beim Vergleichen von 2 Bildern Allgemeine Java-Themen 23
E Swing Array mit Bildern in GUI darstellen Allgemeine Java-Themen 2
I Methoden Schnelle Hilfe benötigt - Kleines Video/Slideshow aus mehreren Bildern erstellen Allgemeine Java-Themen 3
D Tool zum skalieren von bildern Allgemeine Java-Themen 4
X Skalierung von Bildern zum Start des Programms Allgemeine Java-Themen 3
A Metadaten von Bildern auslesen und verändern Allgemeine Java-Themen 5
Kr0e Differenzen von Bildern berechnen - Remote control Allgemeine Java-Themen 2
F hex-farbwert der pixel aus bildern lesen Allgemeine Java-Themen 4
K Thread mit Bildern Allgemeine Java-Themen 3
B Suche Paket zum auslesen von Metadaten von Bildern. Allgemeine Java-Themen 4
L Problem beim animieren von Bildern in Applet Allgemeine Java-Themen 23
K Positionierung von Labels mit Bildern über anderen Allgemeine Java-Themen 8
X Mustererkennung von JPG Bildern Allgemeine Java-Themen 5
data89 Java und HTML-Seiten mit Bildern - Wie passt das zusammen? Allgemeine Java-Themen 2
K Schreiben von Bildern: Bild bleibt leer Allgemeine Java-Themen 7
Q Rotation von Bildern schlägt fehl Allgemeine Java-Themen 8
I Qualität von bearbeiteten Bildern? Allgemeine Java-Themen 3
S software zum zuschneiden von Bildern Allgemeine Java-Themen 2
P Abspeicherung von Bildern Allgemeine Java-Themen 7
T Langsames Laden von Bildern und Heap Exception Allgemeine Java-Themen 7
M transparenz bei png bildern beibehalten Allgemeine Java-Themen 11
A Schnelles laden von Bildern Allgemeine Java-Themen 3
M Problem beim laden von vielen Bildern Allgemeine Java-Themen 16
D Problem mit Bilderupload von lokalen Bildern bei eBay Allgemeine Java-Themen 8
M Strukturen in Bildern vergleichen Allgemeine Java-Themen 6
C Download von Bildern etc. realisieren Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben