BufferedImage逐像素存储),以在JPanel上绘制图像。AffineTransform。小图片(<.5GB)
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);
Run Code Online (Sandbox Code Playgroud)
BigBufferedImage image = BigBufferedImage.create(newCol,newRow, BufferedImage.TYPE_INT_ARGB);但这不能传递给g2d.drawImage(image, 0, 0, this);
JPanel的repaint方法由于某种原因而停止。
我尝试以低分辨率加载图像,其中读取像素,并且跳过/跳过了几列和几行。但是问题是如何确定随着图像大小的变化要跳过多少像素,因此我无法决定如何确定跳转参数。
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++;
}
Run Code Online (Sandbox Code Playgroud)
问题是要决定要跳过多少列和行,即应设置什么跳跃值。
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);
Run Code Online (Sandbox Code Playgroud)
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++;
}
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
获得了以下结果
内存分配
此方法失败,因为根据我的代码使用情况,可用内存增加了。结果,对我来说决定跳下去是没有用的。
一种在加载图像之前访问可用内存量的方法,这样我就可以使用它来决定跳转的值。还有其他选择来决定跳跃值(即,我可以降低多少分辨率吗?)。
您可以读取图像的特定部分,然后以降低的分辨率对其进行缩放以进行显示。
因此,在您的情况下,您可以按块读取图像(读取图像部分就像我们逐行从数据库读取数据一样)
例如:
// Define the portion / row size 50px or 100px
int rowHeight = 50;
int rowsToScan = imageHeight / rowHeight;
if(imageHeight % rowHeight > 0) rowsToScan++;
int x = 0;
int y = 0;
int w = imageWidth;
int h = rowHeight;
ArrayList<BufferedImage> scaledImagePortions = new ArrayList<>();
for(int i = 1; i <= rowsToScan; i++) {
// Read the portion of an image scale it
// and push the scaled version in lets say array
BufferedImage scalledPortionOfImage = this.getScaledPortionOfImage(img, x, y, w, h);
scaledImagePortions.add(scalledPortionOfImage);
y = (rowHeight * i);
}
// Create single image out of scaled images portions
Run Code Online (Sandbox Code Playgroud)
线程可以帮助您从Java中的非常大的图像文件中获取图像的一部分读取区域
线程可以帮助您缩放图像(我的快速搜索结果:)) 如何在java中调整图像大小?
可以帮助您合并缓冲图像的线程:合并两个图像
您随时可以调整片段:)
| 归档时间: |
|
| 查看次数: |
212 次 |
| 最近记录: |