Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-在不损失质量的情况下调整图像大小_Java_Image_Image Processing_Bufferedimage - Fatal编程技术网

Java-在不损失质量的情况下调整图像大小

Java-在不损失质量的情况下调整图像大小,java,image,image-processing,bufferedimage,Java,Image,Image Processing,Bufferedimage,我有10000张照片需要调整大小,所以我有一个Java程序来实现这一点。不幸的是,图像质量很差,我无法访问未压缩的图像 import java.awt.Graphics; import java.awt.AlphaComposite; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.

我有10000张照片需要调整大小,所以我有一个Java程序来实现这一点。不幸的是,图像质量很差,我无法访问未压缩的图像

import java.awt.Graphics;
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;


import javax.imageio.ImageIO;
/**
 * This class will resize all the images in a given folder
 * @author 
 *
 */
public class JavaImageResizer {

    public static void main(String[] args) throws IOException {

        File folder = new File("/Users/me/Desktop/images/");
        File[] listOfFiles = folder.listFiles();
        System.out.println("Total No of Files:"+listOfFiles.length);
        BufferedImage img = null;
        BufferedImage tempPNG = null;
        BufferedImage tempJPG = null;
        File newFilePNG = null;
        File newFileJPG = null;
        for (int i = 0; i < listOfFiles.length; i++) {
              if (listOfFiles[i].isFile()) {
                System.out.println("File " + listOfFiles[i].getName());
                img = ImageIO.read(new File("/Users/me/Desktop/images/"+listOfFiles[i].getName()));
                tempJPG = resizeImage(img, img.getWidth(), img.getHeight());
                newFileJPG = new File("/Users/me/Desktop/images/"+listOfFiles[i].getName()+"_New");
                ImageIO.write(tempJPG, "jpg", newFileJPG);
              }
        }
        System.out.println("DONE");
    }

    /**
     * This function resize the image file and returns the BufferedImage object that can be saved to file system.
     */
        public static BufferedImage resizeImage(final Image image, int width, int height) {
    int targetw = 0;
    int targeth = 75;

    if (width > height)targetw = 112;
    else targetw = 50;

    do {
        if (width > targetw) {
            width /= 2;
            if (width < targetw) width = targetw;
        }

        if (height > targeth) {
            height /= 2;
            if (height < targeth) height = targeth;
        }
    } while (width != targetw || height != targeth);

    final BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    final Graphics2D graphics2D = bufferedImage.createGraphics();
    graphics2D.setComposite(AlphaComposite.Src);
    graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
    graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    graphics2D.drawImage(image, 0, 0, width, height, null);
    graphics2D.dispose();

    return bufferedImage;
}
导入java.awt.Graphics;
导入java.awt.AlphaComposite;
导入java.awt.Graphics2D;
导入java.awt.Image;
导入java.awt.RenderingHints;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入javax.imageio.imageio;
/**
*此类将调整给定文件夹中所有图像的大小
*@作者
*
*/
公共类JavaImageResizer{
公共静态void main(字符串[]args)引发IOException{
文件夹=新文件(“/Users/me/Desktop/images/”);
File[]listOfFiles=folder.listFiles();
System.out.println(“文件总数:“+listOfFiles.length”);
BuffereImage img=null;
BuffereImage tempPNG=null;
BuffereImage tempJPG=null;
文件newFilePNG=null;
文件newFileJPG=null;
for(int i=0;i高度)targetw=112;
否则targetw=50;
做{
如果(宽度>目标宽度){
宽度/=2;
如果(宽度目标){
高度/=2;
如果(高度<目标高度)高度=目标高度;
}
}而(宽度!=targetw | |高度!=targetth);
final BuffereImage BuffereImage=新的BuffereImage(宽度、高度、BuffereImage.TYPE_INT_RGB);
final Graphics2D Graphics2D=bufferedImage.createGraphics();
graphics2D.setComposite(AlphaComposite.Src);
graphics2D.setRenderingHint(RenderingHits.KEY\u插值,RenderingHits.VALUE\u插值\u双线性);
graphics2D.setRenderingHint(RenderingHits.KEY_RENDERING,RenderingHits.VALUE_RENDER_QUALITY);
graphics2D.setRenderingHint(RenderingHits.KEY\u ANTIALIASING,RenderingHits.VALUE\u ANTIALIAS\u ON);
graphics2D.drawImage(图像,0,0,宽度,高度,空);
graphics2D.dispose();
返回缓冲区图像;
}
我正在处理的一个图像是:

这是我在Microsoft Paint中手动调整大小的步骤:

这是我的程序[双线性]的输出:

更新:使用双三次

这是我的程序[bicubic]的输出:

是否有任何方法可以提高程序输出的质量,这样我就不必手动调整所有照片的大小


提前感谢!

鉴于您的输入图像,评论(Chris Campbell的赞誉)第一个链接中的答案中的方法会生成以下缩略图之一:

(另一个是您使用MS Paint创建的缩略图。很难将其中一个称为“比另一个更好…”

编辑:也要指出这一点:原始代码的主要问题是,您没有真正在多个步骤中缩放图像。您只是使用了一个奇怪的循环来“计算”目标大小。关键是您实际上在多个步骤中执行缩放

为了完整起见,MVCE

(编辑:我提到了克里斯·坎贝尔,并通过评论提到了消息来源,但为了更清楚地说明这一点:以下内容基于文章)

导入java.awt.Graphics2D;
导入java.awt.RenderingHints;
导入java.awt.Transparency;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.OutputStream;
导入java.util.Iterator;
导入javax.imageio.IIOImage;
导入javax.imageio.imageio;
导入javax.imageio.ImageWriteParam;
导入javax.imageio.ImageWriter;
导入javax.imageio.stream.ImageOutputStream;
导入javax.imageio.stream.MemoryCacheImageOutputStream;
公共类重新调整质量
{
公共静态void main(字符串[]args)引发IOException
{
BuffereImage image=ImageIO.read(新文件(“X0aPT.jpg”);
BuffereImage scaled=getScaledInstance(
图像,51,75,渲染提示。值\插值\双线性,真);
writeJPG(缩放的新文件输出流(“X0aPT_tn.jpg”),0.85f;
}
公共静态缓冲区映像getScaledInstance(
BuffereImage img,int targetWidth,
int targetHeight,对象提示,
布尔值(高质量)
{
整型=
(img.getTransparency()==Transparency.不透明)
?BufferedImage.TYPE_INT_RGB:BufferedImage.TYPE_INT_ARGB;
BuffereImage ret=(BuffereImage)img;
int w,h;
如果(高质量)
{
//使用多步骤技术:从原始尺寸开始,然后
//使用drawImage()在多个过程中按比例缩小
//直到达到目标大小
w=img.getWidth();
h=img.getHeight();
}
其他的
{
//使用一步技术:直接从原始图像缩放
//通过单个drawImage()调用将大小设置为目标大小
w=目标宽度;
h=目标光;
}
做
{
if(高质量和宽>目标宽度)
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.stream.MemoryCacheImageOutputStream;

public class ResizeQuality
{
    public static void main(String[] args) throws IOException
    {
        BufferedImage image = ImageIO.read(new File("X0aPT.jpg"));
        BufferedImage scaled = getScaledInstance(
            image, 51, 75, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);
        writeJPG(scaled, new FileOutputStream("X0aPT_tn.jpg"), 0.85f);
    }

    public static BufferedImage getScaledInstance(
        BufferedImage img, int targetWidth,
        int targetHeight, Object hint, 
        boolean higherQuality)
    {
        int type =
            (img.getTransparency() == Transparency.OPAQUE)
            ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
        BufferedImage ret = (BufferedImage) img;
        int w, h;
        if (higherQuality)
        {
            // Use multi-step technique: start with original size, then
            // scale down in multiple passes with drawImage()
            // until the target size is reached
            w = img.getWidth();
            h = img.getHeight();
        }
        else
        {
            // Use one-step technique: scale directly from original
            // size to target size with a single drawImage() call
            w = targetWidth;
            h = targetHeight;
        }

        do
        {
            if (higherQuality && w > targetWidth)
            {
                w /= 2;
                if (w < targetWidth)
                {
                    w = targetWidth;
                }
            }

            if (higherQuality && h > targetHeight)
            {
                h /= 2;
                if (h < targetHeight)
                {
                    h = targetHeight;
                }
            }

            BufferedImage tmp = new BufferedImage(w, h, type);
            Graphics2D g2 = tmp.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
            g2.drawImage(ret, 0, 0, w, h, null);
            g2.dispose();

            ret = tmp;
        } while (w != targetWidth || h != targetHeight);

        return ret;
    }

    public static void writeJPG(
        BufferedImage bufferedImage,
        OutputStream outputStream,
        float quality) throws IOException
    {
        Iterator<ImageWriter> iterator =
            ImageIO.getImageWritersByFormatName("jpg");
        ImageWriter imageWriter = iterator.next();
        ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
        imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        imageWriteParam.setCompressionQuality(quality);
        ImageOutputStream imageOutputStream =
            new MemoryCacheImageOutputStream(outputStream);
        imageWriter.setOutput(imageOutputStream);
        IIOImage iioimage = new IIOImage(bufferedImage, null, null);
        imageWriter.write(null, iioimage, imageWriteParam);
        imageOutputStream.flush();
    }    
}
import ij.IJ;
import ij.ImagePlus;
import ij.io.Opener;
import ij.process.ImageProcessor;

public class Resizer {

    public static void main(String[] args) {
        processPicture("X0aPT.jpg", "output.jpg", 0.0198, ImageProcessor.NONE, 0.3);
    }

    public static void processPicture(String inputFile, String outputFilePath, double scaleFactor, int interpolationMethod, double sigmaFactor) {
        Opener opener = new Opener();
        ImageProcessor ip = opener.openImage(inputFile).getProcessor();
        ip.blurGaussian(sigmaFactor / scaleFactor);
        ip.setInterpolationMethod(interpolationMethod);
        ImageProcessor outputProcessor = ip.resize((int)(ip.getWidth() * scaleFactor), (int)(ip.getHeight()*scaleFactor));
        IJ.saveAs(new ImagePlus("", outputProcessor), outputFilePath.substring(outputFilePath.lastIndexOf('.')+1), outputFilePath);
    }

}
File folder = new File("/Users/me/Desktop/images/");
Thumbnails.of(folder.listFiles())
    .size(112, 75)
    .outputFormat("jpg")
    .toFiles(Rename.PREFIX_DOT_THUMBNAIL);
images/fireworks.jpg     ->  images/thumbnail.fireworks.jpg
images/illustration.png  ->  images/thumbnail.illustration.png
images/mountains.jpg     ->  images/thumbnail.mountains.jpg
BufferedImage thumbnail = 
    Thumbnails.of(new URL("http://i.stack.imgur.com/X0aPT.jpg"))
        .height(75)
        .asBufferedImage();

ImageIO.write(thumbnail, "png", new File("24745147.png"));
ResampleOp resizeOp = new ResampleOp(dWidth, dHeight);
resizeOp.setFilter(ResampleFilters.getLanczos3Filter());
BufferedImage scaledImage = resizeOp.filter(imageToScale, null);
Resizer resizer = DefaultResizerFactory.getInstance().getResizer(
  new Dimension(imageToScale.getWidth(), imageToScale.getHeight()), 
  new Dimension(dWidth, dHeight))
BufferedImage scaledImage = new FixedSizeThumbnailMaker(
  dWidth, dHeight, false, true).resizer(resizer).make(imageToScale);
BufferedImage scaledImage = Scalr.resize(imageToScale, Scalr.Method.ULTRA_QUALITY, Scalr.Mode.FIT_EXACT, dWidth, dHeight, bufferedImageOpArray);
BufferedImage scaledImage = new MultiStepRescaleOp(dWidth, dHeight, RenderingHints.VALUE_INTERPOLATION_BILINEAR).filter(imageToScale, null);
scaledImage = new BufferedImage(dWidth, dHeight, imageType);
Graphics2D graphics2D = scaledImage.createGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2D.drawImage(imageToScale, 0, 0, dWidth, dHeight, null);
graphics2D.dispose();
BufferedImage input = ...; // Image to resample
int width, height = ...; // new width/height

BufferedImageOp resampler = new ResampleOp(width, height, ResampleOp.FILTER_LANCZOS);
BufferedImage output = resampler.filter(input, null);
public Image(java.awt.image.BufferedImage bufferedImage)
javaxt.io.Image image = new javaxt.io.Image(bufferedImage);
image.setWidth(50);
image.setOutputQuality(1);
private static BufferedImage progressiveScaling(BufferedImage before, Integer longestSideLength) {
    if (before != null) {
        Integer w = before.getWidth();
        Integer h = before.getHeight();

        Double ratio = h > w ? longestSideLength.doubleValue() / h : longestSideLength.doubleValue() / w;

        //Multi Step Rescale operation
        //This technique is describen in Chris Campbell’s blog The Perils of Image.getScaledInstance(). As Chris mentions, when downscaling to something less than factor 0.5, you get the best result by doing multiple downscaling with a minimum factor of 0.5 (in other words: each scaling operation should scale to maximum half the size).
        while (ratio < 0.5) {
            BufferedImage tmp = scale(before, 0.5);
            before = tmp;
            w = before.getWidth();
            h = before.getHeight();
            ratio = h > w ? longestSideLength.doubleValue() / h : longestSideLength.doubleValue() / w;
        }
        BufferedImage after = scale(before, ratio);
        return after;
    }
    return null;
}

private static BufferedImage scale(BufferedImage imageToScale, Double ratio) {
    Integer dWidth = ((Double) (imageToScale.getWidth() * ratio)).intValue();
    Integer dHeight = ((Double) (imageToScale.getHeight() * ratio)).intValue();
    BufferedImage scaledImage = new BufferedImage(dWidth, dHeight, BufferedImage.TYPE_INT_RGB);
    Graphics2D graphics2D = scaledImage.createGraphics();
    graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    graphics2D.drawImage(imageToScale, 0, 0, dWidth, dHeight, null);
    graphics2D.dispose();
    return scaledImage;
}