Сводка
- Я читаю большой двоичный файл, который содержит данные изображения.
- Кумулятивный анализ Cut Count выполняется для данных [Требуется другой массив с таким же размером, как у изображения].
- Данные растягиваются от 0 до 255 и сохраняются в
BufferedImage
пиксель за пикселем, чтобы нарисовать изображение на JPanel. - На этом изображении масштабирование выполняется с использованием
AffineTransform
.
Проблемы
Маленькое изображение (<. 5 ГБ) </p>
1.1 Когда я увеличиваю масштабный коэффициент для выполнения масштабирования, после
выдается исключение точки: -
java.lang.OutOfMemoryError: пространство кучи Java.
Ниже приведен код, используемый для увеличения-
scaled = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g2d = (Graphics2D)scaled.createGraphics();
AffineTransform transformer = new AffineTransform();
transformer.scale(scaleFactor, scaleFactor);
g2d.setTransform(transformer);
Большое изображение (> 1,5 ГБ)
- При загрузке огромного изображения (> 1,5 ГБ) происходит то же исключение, что и в 1.1, даже если изображение достаточно маленькое для загрузки, иногда я получаюта же ошибка.
Пробные решения
- Я пытался использовать BigBufferedImage вместо BufferedImage для хранения растянутых данных.
BigBufferedImage image = BigBufferedImage.create(newCol,newRow, BufferedImage.TYPE_INT_ARGB);
Но его нельзя передать на g2d.drawImage(image, 0, 0, this);
, потому что метод перерисовки JPanel просто почему-то останавливается.
Я попытался загрузитьизображение в низком разрешении, при котором считывается пиксель, а несколько столбцов и строк прыгают / пропускаются .Но проблема в том, как решить, какое количество пикселей пропустить при изменении размера изображения, поэтому я не могу решить, как определить параметр jump .
MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY,0, inChannel.size());
buffer.order(ByteOrder.LITTLE_ENDIAN);
FloatBuffer floatBuffer = buffer.asFloatBuffer();
for(int i=0,k=0;i<nrow;i=i+jump) /*jump is the value to be skipped, nrow is height of image*/
{
for(int j=0,l=0;j<ncol1;j=j+jump) //ncol is width of image
{
index=(i*ncol)+j;
oneDimArray[(k*ncolLessRes)+l] = floatBuffer.get(index);//oneDimArray is initialised to size of Low Resolution image.
l++;
}
k++;
}
Проблема состоит в том, чтобы решить, сколько столбцов и строк пропустить, т.е. какое значение перехода должно быть установлено.
Я попытался установить Xmx, но размер изображения меняется, и мы
не можем динамически установить значения Xmx.Вот некоторые значения -
table, th, td {
border: 1px solid black;
}
<table style="width:100%">
<tr>
<th>Image Size</th>
<th>Xmx</th>
<th>Xms</th>
<th>Problem</th>
</tr>
<tr>
<td>83Mb</td>
<td>512m</td>
<td>256m</td>
<td>working</td>
</tr>
<tr>
<td>83Mb</td>
<td>3096m</td>
<td>2048m</td>
<td>System hanged</td>
</tr>
<tr>
<td>3.84Gb</td>
<td>512m</td>
<td>256m</td>
<td>java.lang.OutOfMemoryError: Java heap space
</tr>
<tr>
<td>3.84Gb</td>
<td>3096m</td>
<td>512m</td>
<td>java.lang.OutOfMemoryError: Java heap space
</tr>
</table>
Для этого я попытался найти память, выделенную для программы: -
try(BufferedWriter bw= new BufferedWriter(new FileWriter(dtaFile,true))){
Runtime runtime=Runtime.getRuntime();
runtime.gc();
double oneMB=Math.pow(2,20);
long[] arr= Instream.range(0,(int)(10.432*long.BYTES*Math.pow(2,20))).asLongStream().toArray();
runtime.gc();
long freeMemory= runtime.freeMemory();
long totalMemory= runtime.totalMemory();
long usedMemory= totalMemory-freeMemory;
long maxMemory= runtime.maxMemory();
String fileLine= String.format(" %9.3f %9.3f %9.3f " , usedMemory/oneMb, freeMemory/oneMB, totalMemory/oneMb, maxMemory/oneMB);
bw.write();
}
Были получены следующие результаты
Распределение памяти
Этот подход не удался, так как доступныйпамять увеличивается в соответствии с использованием моего кода.В результате для меня будет бесполезно принимать решение о прыжке.
Ожидаемый результат
Способ доступа к количеству доступной памяти перед загрузкой изображения, чтобы я могиспользуйте его, чтобы принять решение о стоимости прыжка.Есть ли другая альтернатива для определения значения jump (т. Е. Насколько я могу уменьшить разрешение?).