Java AlphaComposite混合了大量的质量损失

时间:2015-09-17 19:42:11

标签: java bufferedimage java-2d alphablending

我正在使用间隔拍摄摄影,并试图通过将多张照片混合到一帧来实现脚本来平滑过渡。像照片1到30一样产生第1帧,照片2到31产生第2帧,依此类推。

当我尝试用GIMP合并30张连续照片时,效果非常顺畅;当我使用Java BufferedImages和AlphaComposite实现相同的逻辑时,我得到了似乎不可接受的压缩工件。

我已经尝试了不同的东西,比如用无压缩的ImageWriter替换ImageIO.write(),但结果几乎相同。现在我没有想法。可能是AlphaComposite混合会导致质量损失吗?

GIMP generated image

Java generated image

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.imageio.ImageIO;

public class SimplePhotoBlender {

    public static void main(String[] args) throws IOException {
        if (args.length < 1)
            System.out.println("Usage: java SimplePhotoBlender <PATH_TO_IMAGE_FOLDER>");
        else
            new SimplePhotoBlender(args[0]);
    }

    public SimplePhotoBlender(String path) throws IOException {
        // Get all images in folder
        List<File> fileList = getFilesInFolder(new File(path));
        Collections.sort(fileList);

        // Iterate through the list ...
        for (int i = 0; i < fileList.size(); i++) {

            File originalImage = fileList.get(i);
            BufferedImage blended = ImageIO.read(originalImage);

            // ... and blend it with the following 30 images.
            for (int j = 1; j <= 30 && i + j < fileList.size() - 1; j++)
                blended = blend(blended, ImageIO.read(fileList.get(i + j)), 0.9);

            // Finally, save it in a new file.
            File blendedFile = new File(originalImage.getParent() + "/blended/" + originalImage.getName());
            blendedFile.getParentFile().mkdirs();
            blendedFile.createNewFile();

            // I double-checked but the JPG compression in ImageIO.write()
            // doesn't account for the tremendous amount of quality loss.
            ImageIO.write(blended, "jpg", blendedFile);
        }
    }

    // Needless to say that I copied this from the sources like
    // http://www.informit.com/articles/article.aspx?p=1245201&seqNum=2
    private BufferedImage blend(BufferedImage bi1, BufferedImage bi2, double weight) {

        BufferedImage bi3 = new BufferedImage(bi1.getWidth(), bi1.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = bi3.createGraphics();
        g2d.drawImage(bi1, null, 0, 0);
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) (1.0 - weight)));
        g2d.drawImage(bi2, null, 0, 0);
        g2d.dispose();

        return bi3;
    }

    public List<File> getFilesInFolder(final File folder) {
        List<File> fileNames = new ArrayList<>();
        for (final File fileEntry : folder.listFiles())
            if (!fileEntry.isDirectory())
                fileNames.add(fileEntry);
        return fileNames;
    }
}

0 个答案:

没有答案