使图像 resize() 的代码起作用

发布于 2024-07-17 12:29:34 字数 3397 浏览 5 评论 0原文

我的导师向我发送了这段代码,它应该是正在进行的项目的组成部分。 问题是,它不起作用。

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.Kernel;
import java.awt.image.ConvolveOp;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import javax.swing.*;


public class ImageUtil {

    public static void resize(File originalFile, File resizedFile, int newWidth, float quality) throws IOException{

        if(quality <0||quality>1){
            throw new IllegalArgumentException ("quality has to be between 0 and 1");

        }

        ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
        Image i = ii.getImage();
        Image resizedImage = null;

        int iWidth = i.getWidth (null);
        int iHeight = i.getHeight(null);

        if (iWidth > iHeight){
            resizedImage = i.getScaledInstance(newWidth,(newWidth*iHeight)/iWidth, Image.SCALE_SMOOTH);
        } else {
            resizedImage = i.getScaledInstance((newWidth*iWidth)/iHeight,newWidth, Image.SCALE_SMOOTH);
        }

        Image temp = new ImageIcon (resizedImage).getImage();

        BufferedImage bufferedImage = new BufferedImage (temp.getWidth(null), temp.getHeight(null),
                                                         BufferedImage.TYPE_INT_RGB);

        // copy to a buffered image
        Graphics g = bufferedImage.createGraphics();

        g.setColor(Color.white);
        g.fillRect(0,0,temp.getWidth(null), temp.getHeight(null)); // causea el error de ejecución?
        g.drawImage(temp,0,0,null);
        g.dispose();

        float softenFactor = 0.05f;
        float [] softenArray = {0, softenFactor,0, softenFactor, 1-(softenFactor*4), softenFactor,0, softenFactor,0};
        Kernel kernel = new Kernel (3,3,softenArray);
        ConvolveOp cOp = new ConvolveOp (kernel, ConvolveOp.EDGE_NO_OP,null);
        bufferedImage = cOp.filter (bufferedImage,null);

        FileOutputStream out = new FileOutputStream(resizedFile);

        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);

        JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);

        param.setQuality(quality,true);

        encoder.setJPEGEncodeParam(param);
        encoder.encode(bufferedImage);



    }

    public static void main(String args[]) throws IOException {
       File originalImage= new File ("/images/goya.jpg");
       resize(originalImage,new File("/images/goyanuevotamanio.jpg"),350, 0.2f);
       resize(originalImage, new File("/images/goyanuevotamanio.jpg"), 350, 1f);

    }

}

他说代码应该能够调整高度和宽度,但他的调整大小方法:

public static void resize(File originalFile, File resizedFile, int newWidth, float quality)

缺少 newHeight 参数。

抛出的 RuntimeException 说:

Exception in thread "main" java.lang.IllegalArgumentException: **Width (-1) and height (-1) cannot be <= 0**
        at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:999)
        at java.awt.image.BufferedImage.<init>(BufferedImage.java:312)
        at ImageUtil.resize(ImageUtil.java:38)
        at ImageUtil.main(ImageUtil.java:72)
Java Result: 1

我怎样才能改变这个?

My instructor sent me this code, which is supposed to be an integral part of an ongoing project. Thing is, it doesn't work.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.Kernel;
import java.awt.image.ConvolveOp;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import javax.swing.*;


public class ImageUtil {

    public static void resize(File originalFile, File resizedFile, int newWidth, float quality) throws IOException{

        if(quality <0||quality>1){
            throw new IllegalArgumentException ("quality has to be between 0 and 1");

        }

        ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
        Image i = ii.getImage();
        Image resizedImage = null;

        int iWidth = i.getWidth (null);
        int iHeight = i.getHeight(null);

        if (iWidth > iHeight){
            resizedImage = i.getScaledInstance(newWidth,(newWidth*iHeight)/iWidth, Image.SCALE_SMOOTH);
        } else {
            resizedImage = i.getScaledInstance((newWidth*iWidth)/iHeight,newWidth, Image.SCALE_SMOOTH);
        }

        Image temp = new ImageIcon (resizedImage).getImage();

        BufferedImage bufferedImage = new BufferedImage (temp.getWidth(null), temp.getHeight(null),
                                                         BufferedImage.TYPE_INT_RGB);

        // copy to a buffered image
        Graphics g = bufferedImage.createGraphics();

        g.setColor(Color.white);
        g.fillRect(0,0,temp.getWidth(null), temp.getHeight(null)); // causea el error de ejecución?
        g.drawImage(temp,0,0,null);
        g.dispose();

        float softenFactor = 0.05f;
        float [] softenArray = {0, softenFactor,0, softenFactor, 1-(softenFactor*4), softenFactor,0, softenFactor,0};
        Kernel kernel = new Kernel (3,3,softenArray);
        ConvolveOp cOp = new ConvolveOp (kernel, ConvolveOp.EDGE_NO_OP,null);
        bufferedImage = cOp.filter (bufferedImage,null);

        FileOutputStream out = new FileOutputStream(resizedFile);

        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);

        JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);

        param.setQuality(quality,true);

        encoder.setJPEGEncodeParam(param);
        encoder.encode(bufferedImage);



    }

    public static void main(String args[]) throws IOException {
       File originalImage= new File ("/images/goya.jpg");
       resize(originalImage,new File("/images/goyanuevotamanio.jpg"),350, 0.2f);
       resize(originalImage, new File("/images/goyanuevotamanio.jpg"), 350, 1f);

    }

}

He says the code should be able to resize both height and width yet his resize method:

public static void resize(File originalFile, File resizedFile, int newWidth, float quality)

lacks a newHeight parameter.

The RuntimeException that's thrown says:

Exception in thread "main" java.lang.IllegalArgumentException: **Width (-1) and height (-1) cannot be <= 0**
        at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:999)
        at java.awt.image.BufferedImage.<init>(BufferedImage.java:312)
        at ImageUtil.resize(ImageUtil.java:38)
        at ImageUtil.main(ImageUtil.java:72)
Java Result: 1

How can I change this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

深府石板幽径 2024-07-24 12:29:35

从堆栈跟踪来看,这一行抛出了异常:

BufferedImage bufferedImage = new BufferedImage (temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_RGB);

我认为这可能是因为 temp.getWidthtemp.getHeight 返回 -1,因为图像没有加载完成。

Web 上提供了使用 Java 处理图像的教程和示例。 一个示例位于此处 http://snippets.dzone.com/posts/show/92。 使用ImageObserver查找代码。

Judging by the stack trace the exception is thrown by this line:

BufferedImage bufferedImage = new BufferedImage (temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_RGB);

I would think this is probably because temp.getWidth and temp.getHeight are returning -1 because the image has not finished loading.

There are tutorials and examples for working with images in Java available on the web. One sample is here http://snippets.dzone.com/posts/show/92. Look for the code using ImageObserver.

俏︾媚 2024-07-24 12:29:35

您必须为程序提供一个介于 0 和 1 之间的起始参数。
我做到了并且效果非常好。

You have to give the program a starting parameter between 0 and 1.
I did it and it work perfectly.

酒浓于脸红 2024-07-24 12:29:35

适应这个:

private void ResizeImage(Image img, double maxWidth, double maxHeight)
{
    double srcWidth = img.Source.Width;
    double srcHeight = img.Source.Height;

    double resizeWidth = srcWidth;
    double resizeHeight = srcHeight;

    double aspect = resizeWidth / resizeHeight;

    if (resizeWidth > maxWidth)
    {
        resizeWidth = maxWidth;
        resizeHeight = resizeWidth / aspect;
    }
    if (resizeHeight > maxHeight)
    {
        aspect = resizeWidth / resizeHeight;
        resizeHeight = maxHeight;
        resizeWidth = resizeHeight * aspect;
    }

    img.Width = resizeWidth;
    img.Height = resizeHeight;
}

adapt this:

private void ResizeImage(Image img, double maxWidth, double maxHeight)
{
    double srcWidth = img.Source.Width;
    double srcHeight = img.Source.Height;

    double resizeWidth = srcWidth;
    double resizeHeight = srcHeight;

    double aspect = resizeWidth / resizeHeight;

    if (resizeWidth > maxWidth)
    {
        resizeWidth = maxWidth;
        resizeHeight = resizeWidth / aspect;
    }
    if (resizeHeight > maxHeight)
    {
        aspect = resizeWidth / resizeHeight;
        resizeHeight = maxHeight;
        resizeWidth = resizeHeight * aspect;
    }

    img.Width = resizeWidth;
    img.Height = resizeHeight;
}
离去的眼神 2024-07-24 12:29:34

在不分析代码以了解问题所在的情况下,我可以说,如果目的是保持图像的宽高比,则不需要新的高度参数。 它始终是固定的宽度比。

更新:

我已经针对我自己的测试图像运行了代码,它确实按预期工作。 您收到的错误很可能是当程序找不到您指定的源图像时引起的。 当我指定不存在的源图像时,我收到相同的错误。

尝试对源图像使用绝对路径(包括驱动器号等)。

更新2

在该行后添加以下代码。

ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());

if(ii.getImageLoadStatus() == MediaTracker.COMPLETE)
{
    System.out.print("Load image ok\n");
}
else
{
    System.out.print("Load image failed\n");
}

这将告诉您程序是否无法加载源图像。

Without analyzing the code to see what the problem might be, I can say that if the intention is to keep the images aspect ratio, a new height parameter is not needed. It will always be a fixed ratio of the width.

UPDATE:

I've run the code against my own test image and it does indeed work as expected. The error you are getting is most likely caused when the program cannot find the source image you specify. I get the same error when I specify a source image that doesn't exist.

Try using an absolute path (including drive letter etc.) for your source image.

UPDATE 2

Add the following code after the line..

ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());

if(ii.getImageLoadStatus() == MediaTracker.COMPLETE)
{
    System.out.print("Load image ok\n");
}
else
{
    System.out.print("Load image failed\n");
}

This will tell you if the program is failing to load the source image.

初熏 2024-07-24 12:29:34

为什么你应用软化来调整大小它必须锐化 Kernal -1 -2 -1 -2 12+q -2 -1 -2 -1 其中典型的 q 可能是 28 并且你没有应用drawImage

(q = 36 相当于锐化的 F=0.05)

Why you apply soften to resize it have to be sharpen Kernal -1 -2 -1 -2 12+q -2 -1 -2 -1 where a tipical q could be 28 and you are not applyng the resize version of drawImage

(q = 36 is equivalent to your F=0.05 for sharpen)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文