java 图像在 JPanel 或 JLabel 中调整大小和显示而不会降低质量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12660122/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Image resizing and displaying in a JPanel or a JLabel without loss of quality
提问by Dilshan Ranaweera
I'm developing a java program to capture employee images at the time of registration using a webcam. I can obtain the picture without any problem, and save it in my C: drive but upon retrieval of the image only a part of the image is displayed on the label. Is there a way of re sizing the JPEG before saving it? or before displaying it? like shrinking it without a quality loss....
我正在开发一个 Java 程序来使用网络摄像头在注册时捕获员工图像。我可以毫无问题地获取图片,并将其保存在我的 C: 驱动器中,但在检索图像时,标签上仅显示图像的一部分。有没有办法在保存之前调整 JPEG 的大小?还是在显示之前?就像在没有质量损失的情况下缩小它......
Thankz a lot Cheerz! :)!
非常感谢Cheerz!:)!
okay guys... here goes:- I have commented the code in the way I have used them.
好吧,伙计们......这里是:-我已经按照我使用它们的方式对代码进行了评论。
//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");
}
}
maybe I can scale the image while saving.. so that I can retrieve the scaled image..
也许我可以在保存时缩放图像..以便我可以检索缩放的图像..
回答by David Kroukamp
Of course you can resize the image there are many different ways like Image#getScaledInstance(int width,int height,int hints)
, but this has its perils.
当然,您可以通过多种不同的方式来调整图像大小Image#getScaledInstance(int width,int height,int hints)
,但这有其危险。
The main problem being:
主要问题是:
Image.getScaledInstance() does not return a finished, scaled image. It leaves much of the scaling work for a later time when the image pixels are used.
Image.getScaledInstance() 不返回完成的缩放图像。当使用图像像素时,它将大部分缩放工作留到以后进行。
I would not recommend using it but hereis a nice example.
我不推荐使用它,但这里有一个很好的例子。
Alternatively you can use this method:
或者,您可以使用此方法:
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;
}
}
you'd use it like:
你会像这样使用它:
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));
UPDATE:
更新:
Here is a small example I made:
这是我制作的一个小例子:
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;
}
}
References:
参考: