随着你的提示和问题,我可以写一个实际上做我想做的事的类。它可能不会缩放所有尺寸,但适用于非常大的图像。表现非常糟糕(10-15秒为1300 x 27000 png),但它适用于我的目的。
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import net.coobird.thumbnailator.Thumbnails;
public class ImageManager {
private int tileHeight;
private String pathSubImgs;
/**
* @param args
*/
public static void main(String[] args) {
int tileHeightL = 2000;
String imageBasePath = "C:.../screenshots/";
String subImgsFolderName = "subImgs/";
String origImgName = "TestStep_319_20150601161652.png";
String outImgName = origImgName+"scaled.png";
ImageManager imgMngr = new ImageManager(tileHeightL,imageBasePath+subImgsFolderName);
if(imgMngr.scaleDown(imageBasePath+origImgName, imageBasePath+outImgName))
System.out.println("Scaled.");
else
System.out.println("Failed.");
}
/**
* @param origImgPath
* @param outImgPath
* @param tileHeight
* @param pathSubImgs
*/
public ImageManager(int tileHeight,
String pathSubImgs) {
super();
this.tileHeight = tileHeight;
this.pathSubImgs = pathSubImgs;
}
private boolean scaleDown(String origImgPath, String outImgPath){
try {
BufferedImage image = ImageIO.read(new File(origImgPath));
int origH = image.getHeight();
int origW = image.getWidth();
int tileRestHeight;
int yTiles = (int) Math.ceil(origH/tileHeight);
int tyleMod = origH%tileHeight;
for(int tile = 0; tile <= yTiles ; tile++){
if(tile == yTiles)
tileRestHeight = tyleMod;
else
tileRestHeight = tileHeight;
BufferedImage out = image.getSubimage(0, tile * tileHeight, origW, tileRestHeight);
ImageIO.write(out, "png", new File(pathSubImgs + tile + ".png"));
Thumbnails.of(new File(pathSubImgs + tile + ".png"))
.size(400, 400)
.toFile(new File(pathSubImgs + tile + ".png"));
}
image = ImageIO.read(new File(pathSubImgs + 0 + ".png"));
BufferedImage img2;
for(int tile = 1; tile <= yTiles ; tile++){
if(tile == yTiles)
tileRestHeight = tyleMod;
else
tileRestHeight = tileHeight;
img2 = ImageIO.read(new File(pathSubImgs + tile + ".png"));
image = joinBufferedImage(image, img2);
}
ImageIO.write(image, "png", new File(outImgPath));
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public static BufferedImage joinBufferedImage(BufferedImage img1,BufferedImage img2) {
//do some calculate first
int height = img1.getHeight()+img2.getHeight();
int width = Math.max(img1.getWidth(),img2.getWidth());
//create a new buffer and draw two image into the new image
BufferedImage newImage = new BufferedImage(width,height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = newImage.createGraphics();
Color oldColor = g2.getColor();
//fill background
g2.setPaint(Color.WHITE);
g2.fillRect(0, 0, width, height);
//draw image
g2.setColor(oldColor);
g2.drawImage(img1, null, 0, 0);
g2.drawImage(img2, null, 0, img1.getHeight());
g2.dispose();
return newImage;
}
}
只是加载原始图像运行你内存不足?还是它调整了内存不足? – satnam
你看过ImageProducer/ImageConsumer吗?不记得是否有生产者加载成块,但这是你需要的:加载图像的块,缩小它们并在处理下一个块之前写入文件。如果没有默认制作者,你必须自己解码图片。编辑:如果您找到合适的制作人,您可以使用PixelGrabber为您完成这项工作。 – BeyelerStudios
具有24位颜色深度的原始图像应该只消耗100兆字节(133为32位颜色深度)。 – biziclop