【问题标题】:Image resizing and displaying in a JPanel or a JLabel without loss of quality在 JPanel 或 JLabel 中调整图像大小和显示而不会降低质量
【发布时间】:2012-09-21 12:37:10
【问题描述】:

我正在开发一个 java 程序,用于在注册时使用网络摄像头捕获员工图像。我可以毫无问题地获取图片,并将其保存在我的 C: 驱动器中,但在检索图像时,标签上仅显示部分图像。有没有办法在保存之前调整 JPEG 的大小?还是在显示之前?就像在没有质量损失的情况下缩小它......

非常感谢 干杯! :)!

好的,伙计们...这里是:- 我已经按照我使用它们的方式注释了代码。

//This method will capture the image from the interface and save it under the unique employee ID
public String captureImage(int picId){

    FrameGrabbingControl ControlFG = (FrameGrabbingControl)

    broadcast.getControl("javax.media.control.FrameGrabbingControl");

    Buffer buffer = ControlFG.grabFrame();

    BufferToImage image = new BufferToImage((VideoFormat)buffer.getFormat());

    img = image.createImage(buffer);

    path="c:\\employee"+picId+".jpg";

    saveJPG(img,path);//method will save the image

    return path;

}

 public void saveJPG(Image img, String s){***//method will save the image***

    System.out.println(s);

    BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null),

    BufferedImage.TYPE_INT_RGB);

    Graphics2D g2 = bi.createGraphics();

    g2.drawImage(img,null,null);

    FileOutputStream out = null;
    try{

    out = new FileOutputStream(s);

    }
    catch (java.io.FileNotFoundException io){

    System.out.println("File Not Found");
    }

    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);

    JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);

    param.setQuality(0.5f,false);

    encoder.setJPEGEncodeParam(param);

    try
    {
    encoder.encode(bi);
    out.close();
    }

    catch (java.io.IOException io)
    {
    System.out.println("IOException");
    }
    }

也许我可以在保存时缩放图像.. 这样我就可以检索缩放后的图像..

【问题讨论】:

  • “在不损失质量的情况下缩小它” 这是不可能的。各种平滑技术可以部分隐藏图像调整大小的伪影,但以 WxH 为单位降低分辨率,图像“质量”必须更低。
  • @AndrewThompson 是的,这是真的......质量下降是可以的,但整个图像没有显示......到目前为止,我只能获得缩小图像的一部分......
  • 如需尽快获得更好的帮助,请发帖 SSCCE。也许热链接到these images 之一。
  • 为了尽快获得更好的帮助(除了提供SSCCE,正如@AndrewThompson 已经提到的那样)尝试通过a)学习并坚持Java命名约定b)完全(并且始终如一地)使阅读您的问题变得愉快! ) 格式化代码(有一个帮助按钮,点击时会显示操作方法:-)
  • 如果您真的对质量感兴趣,没有任何办法可以阅读 graphics2D 选项的基础知识,f.i.早期的博客today.java.net/pub/a/today/2007/04/03/… 或 filtyRichClients

标签: java swing jpanel jpeg jlabel


【解决方案1】:

当然,您可以通过多种不同方式调整图像大小,例如Image#getScaledInstance(int width,int height,int hints),但this has its perils

主要问题是:

Image.getScaledInstance() 不返回完成的缩放图像。它 当图像像素时,将大部分缩放工作留给以后的时间 被使用了。

我不建议使用它,但 here 是一个很好的例子。

您也可以使用此方法:

import javax.swing.ImageIcon;
import java.awt.image.BufferedImage;
import java.awt.Image;
import java.awt.Color;
import java.awt.Graphics2D;
import java.io.File;
import javax.imageio.ImageIO;
import java.awt.RenderingHints;

public class ImgUtils {

public BufferedImage scaleImage(int WIDTH, int HEIGHT, String filename) {
    BufferedImage bi = null;
    try {
        ImageIcon ii = new ImageIcon(filename);//path to image
        bi = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = (Graphics2D) bi.createGraphics();
        g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY));
        g2d.drawImage(ii.getImage(), 0, 0, WIDTH, HEIGHT, null);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
    return bi;
}

}

你会像这样使用它:

final BufferedImage img=new ImgUtils().scaleImage(200,200,"c:/test.jpg");
//create label with image as background
JLabel label=new JLabel(new ImageIcon((Image)img));

更新:

这是我做的一个小例子:

import java.awt.BorderLayout;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class JavaApplication117 {

    //change this to your own
    static String filename="c:/test.jpg";

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new JavaApplication117().createAndShowUI();
            }
        });
    }

    private void createAndShowUI() {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        initComponents(frame);

        frame.setResizable(false);
        frame.pack();
        frame.setVisible(true);
    }

    private void initComponents(JFrame frame) {
        final BufferedImage img = new ImgUtils().scaleImage(200, 200, filename);
        //create label with image as background
        JLabel label = new JLabel(new ImageIcon((Image) img));

        frame.getContentPane().add(label, BorderLayout.CENTER);
    }
}

class ImgUtils {

    public BufferedImage scaleImage(int WIDTH, int HEIGHT, String filename) {
        BufferedImage bi = null;
        try {
            ImageIcon ii = new ImageIcon(filename);//path to image
            bi = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = (Graphics2D) bi.createGraphics();
            g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
            g2d.drawImage(ii.getImage(), 0, 0, WIDTH, HEIGHT, null);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return bi;
    }
}

参考资料:

【讨论】:

  • 我修改了代码...以便返回的缓冲图像显示在 jlabel 上,但完整的图像仍然没有显示在标签上,我会尝试覆盖并找回你..再次感谢!:)!
  • 是否有充分的理由扩展JLabel 而不是简单地将图像设置为JLabel 上的图标而没有其他任何东西?
  • @DavidKroukamp 不,图像仍然没有缩小......只显示图像的一部分......!
  • @DilshanRanaweera 然后是其他问题。看我的更新。如果它仍然不起作用,那么我建议发布SSCCE
  • 当心:如果缩小比例/高度小于原来的一半左右,质量会下降..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-12
  • 1970-01-01
  • 1970-01-01
  • 2011-01-24
  • 1970-01-01
相关资源
最近更新 更多