Groß dimensionierte Bilder führen zu einer OufOfMemoryException
-
28-10-2019 - |
Frage
Ich verwende OpenMap und muss sehr großformatige Bilder laden.
Ich habe versucht, diese Bilder als großes Raster zu laden, was mit einer OufOfMemoryException fehlschlägt.Im Debug-Modus teilt mir der Layer-Konstruktor mit, dass die Bildabmessungen zu groß sind.
In einer OpenMap-Mailingliste habe ich das MyJAIPlugin gefunden, mit dem ich GeoTiff-Dateien laden und anzeigen kann.
Wie kann ich ein 300-MB-GeoTiff in OpenMap anzeigen?
Lösung
Ich hatte fast die gleiche Situation, als ich HD-Karten mit einer Dateigröße von mindestens 690 MB geladen habe.
Ich habe auch das JAIPlugIn aus der Mailingliste verwendet und intern verwenden sie das OMScalingRaster, das mit einem BufferedImage arbeitet. Dies begrenzt Ihre Bildgröße und verursacht die Debug-Meldung.
Ich habe es gelöst, indem ich den OMScalingRaster geändert habe. Ich habe das BufferedImage in ein TiledImage geändert, um große Bilder zu verarbeiten, und die bevorstehenden Fehler behoben. Hier ist es wichtig, dass Sie die scaleTo (Projection thisProj) -Methode ändern, um sie mit JAI zu skalieren.
Jetzt kann ich die Datei laden und sie wird auf der Karte gerendert. Wenn Sie jedoch zu stark herauszoomen, wird eine OutOfMemoryException ausgelöst, da ich in meiner Änderung ein Teilbild des sichtbaren Teils des Bildes erstelle und es dem OMRaster als BufferedImage gebe.
Hier ist der Mod. am Ende der scaleTo-Methode:
// Now we can grab the bit we want out of the source
// and
// scale it to fit the intersection.
// Calc width adjustment
float widthAdj = (float) ((double) iRect.width
/ (double) clipRect.width);
// Calc height adjustment
float heightAdj = (float) ((double) iRect.height
/ (double) clipRect.height);
// Create the transform
// JAI-Version
ParameterBlock pb = new ParameterBlock();
pb.addSource(sourceImage.getSubImage(clipRect.x,
clipRect.y,
clipRect.width,
clipRect.height).getAsBufferedImage());
pb.add(widthAdj); // The xScale
pb.add(heightAdj); // The yScale
pb.add(0.0F); // The x translation
pb.add(0.0F); // The y translation
RenderedOp newImage = JAI.create("scale",pb, null);
bitmap = newImage.getAsBufferedImage();
point1.setLocation(iRect.x, iRect.y);
// setVisible(currentVisibility);
}
} else {
bitmap = null;
}
}
Verwenden Sie für die anderen Fehler durch Ersetzen von BufferedImage durch TiledImage die entsprechenden TiledImage-Methoden. Um Speicherplatz zu sparen, sollten Sie den TiledImage-Konstruktor mit dem sharedDataBuffer-Flag= true verwenden.
Zum Beispiel diesen Mod. kann Karten (komprimierte 690 MB) mit einer Skalierung von 1: 50000 verarbeiten und ich kann auf 1: 600000 verkleinern, bevor der Layer angibt, dass ihm der Speicher ausgeht.