我已经尝试过关于编写/保存图像的Oracle建议,但我没有做任何工作。我有一个开始按钮,可以将两个图像从一个图像混合到另一个图像。然后一个停止按钮停止混合中途(或任何你想要的)然后我有一个saveImage按钮,并希望它捕获图像的当前状态并将其保存到文件。但是怎么样?这是Frame.java的代码
import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.Timer;
class Frame extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
private Image MeSmaller1;
private Image MeSmaller2;
protected Timer timer;
private float alpha;
JPanel pnlButton = new JPanel();
static JButton btnStartBlend = new JButton("Start Blend");
static JButton btnStopBlend = new JButton("Stop Blend");
static JButton saveImage = new JButton("Save Image To File");
public Frame() {
loadImages();
initTimer();
pnlButton.add(btnStartBlend);
this.add(pnlButton);
pnlButton.add(btnStopBlend);
this.add(pnlButton);
pnlButton.add(saveImage);
this.add(pnlButton);
addListeners();
}
// start button actionlistener
public void addListeners() {
btnStartBlend.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
initTimer();
timer.start();
System.out.println("Timer started");
}
});
// stop button actionlistener
btnStopBlend.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// initTimer();
timer.stop();
System.out.println("Timer stopped");
}
});
// Save button actionlistener
saveImage.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Save image clicked");
}
});
}
private void loadImages() {
MeSmaller1 = new ImageIcon("MeSmaller1.jpg").getImage();
MeSmaller2 = new ImageIcon("MeSmaller2.jpg").getImage();
}
public void initTimer() {
timer = new Timer(1000, this);
timer.start();
timer.stop();
alpha = 1f;
}
private void doDrawing(Graphics g) {
Graphics2D g2Dim = (Graphics2D) g;
// below sets the size of picture
BufferedImage buffImage = new BufferedImage(400, 600,
BufferedImage.TYPE_INT_ARGB);
Graphics2D gBuffI = buffImage.createGraphics();
AlphaComposite aComp = AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, alpha);
// decides where images are drawn in JFrame
gBuffI.drawImage(MeSmaller1, 28, 55, null);
gBuffI.setComposite(aComp);
gBuffI.drawImage(MeSmaller2, 30, 48, null);
g2Dim.drawImage(buffImage, 10, 10, null);
}
public static void saveToFile(BufferedImage img) {
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
@Override
public void actionPerformed(ActionEvent e) {
alpha -= 0.1;
if (alpha <= 0) {
alpha = 0;
timer.stop();
System.out.println("Morph Finished please restart.");
}
repaint();
}
}
任何人都可以在这里帮助它只是不工作。还有另一个类PictureMorph.java
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class PictureMorph extends JFrame {
private static final long serialVersionUID = 1L;
public PictureMorph() {
initUI();
}
private void initUI() {
JFrame frame = new JFrame ("Image Morph");
setTitle("Facial Image Manipulation");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(new Frame());
// below set Frame Size around image
setSize(380, 470);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
PictureMorph picMorph = new PictureMorph();
picMorph.setVisible(true);
}
});
}
}
3个类(我认为现在实际上可能是多余的?)称为BtnStartBlendListener,BtnStopBlendListener,SaveImageListener,根本不包含太多代码。有人可以帮忙吗?
答案 0 :(得分:0)
由于您已将saveToFile方法留空,我认为这是您遇到的主要问题。
对于saveToFile方法,您可以使用javax.imageio.ImageIO。我建议您将File对象参数传递给您的方法,以便它知道保存图像的位置。
public static void saveToFile(BufferedImage img, File file) {
String filename = file.getName();
String suffix = filename.substring(filename.lastIndexOf('.') + 1);
suffix = suffix.toLowerCase();
if (suffix.equals("jpg") || suffix.equals("png")) {
try { ImageIO.write(img, suffix, file); }
catch (IOException e) { e.printStackTrace(); }
}
else {
System.out.println("Error: filename must end in .jpg or .png");
}
}
希望这有帮助
<强> [编辑] 强>
File构造函数允许您使用表示文件路径的字符串来实例化File对象。
示例:假设我想保存它,让我们说C:\ Tests \ image1.jpg,我会这样做
File myFile = new File("C:\\Tests\\image1.jpg")
,其中Tests表示现有文件夹,image1.jpg当然是新文件的名称,您可以在其中保存图像。
因此假设img是一个包含对BufferedImage对象的引用的变量,您可以使用
调用上面的方法Frame.saveToFile(img, myFile);
其中myFile是上面的File对象。
您还可以添加静态方法(如下所示)以使用户指定文件的路径。我使用Scanner快速获取它,但是为了更方便用户使用对话框,请使用JFileChooser(示例为here)
public static void save(BufferedImage img) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the file name: ");
String fileFullPath = scan.next();
File file = new File(fileFullPath);
saveToFile(img, file);
}
答案 1 :(得分:0)
您遇到的问题主要与您最终声明了一些变量这一事实有关,尤其是BufferedImage和File对象(它们为null,因为您将它们设置为final,它们的值无法更改)< / p>
我纠正了这些问题。以下是整个代码,除了import语句与您在源代码链接中的语句相同。
单击保存按钮后,输入要保存的文件的完整路径:控制台中的示例C:\ test1.jpg。
class Frame extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
static BufferedImage bufferedImage = null; // Don't need to make this final
static File file = null; // Don't need to make this final
private Image MeSmaller1;
private Image MeSmaller2;
protected Timer timer;
private float alpha;
JPanel pnlButton = new JPanel();
static JButton btnStartBlend = new JButton("Start Blend");
static JButton btnStopBlend = new JButton("Stop Blend");
static JButton saveImage = new JButton("Save Image To File");
public Frame() {
loadImages();
initTimer();
pnlButton.add(btnStartBlend);
this.add(pnlButton);
pnlButton.add(btnStopBlend);
this.add(pnlButton);
pnlButton.add(saveImage);
this.add(pnlButton);
addListeners();
}
// start button action listener
public void addListeners() {
btnStartBlend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
initTimer();
timer.start();
System.out.println("Timer started");
}
});
// stop button actionlistener
btnStopBlend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// initTimer();
timer.stop();
System.out.println("Timer stopped");
}
});
// Save button actionlistener
saveImage.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent saveImage) {
save(bufferedImage);
System.out.println("Save image clicked");
}
});
}
private void loadImages() {
// I did my local test using
//MeSmaller1 = new ImageIcon("C:\\Tests\\Alain_Lompo.jpg").getImage();
//MeSmaller2 = new ImageIcon("C:\\Tests\\Alain_Lompo.jpg").getImage();
MeSmaller1 = new ImageIcon("MeSmaller1.jpg").getImage();
MeSmaller2 = new ImageIcon("MeSmaller2.jpg").getImage();
}
public void initTimer() {
timer = new Timer(1000, this);
timer.start();
timer.stop();
alpha = 1f;
}
private void doDrawing(Graphics g) {
Graphics2D g2Dim = (Graphics2D) g;
// below sets the size of picture
bufferedImage = new BufferedImage(400, 600,
BufferedImage.TYPE_INT_ARGB);
Graphics2D gBuffI = bufferedImage.createGraphics();
AlphaComposite aComp = AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, alpha);
// decides where images are drawn in JFrame
gBuffI.drawImage(MeSmaller1, 28, 55, null);
gBuffI.setComposite(aComp);
gBuffI.drawImage(MeSmaller2, 30, 48, null);
g2Dim.drawImage(bufferedImage, 10, 10, null);
}
public static void save(BufferedImage img) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the file name: ");
String fileFullPath = scan.next();
file = new File(fileFullPath);
saveToFile(img, file);
}
public static void saveToFile(BufferedImage img, File file) {
String filename = file.getName();
String suffix = filename.substring(filename.lastIndexOf('.') + 1);
suffix = suffix.toLowerCase();
if (suffix.equals("jpg") || suffix.equals("png")) {
try { ImageIO.write(img, suffix, file); }
catch (IOException e) { e.printStackTrace(); }
}
else {
System.out.println("Error: filename must end in .jpg or .png");
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
public void actionPerformed(ActionEvent e) {
alpha -= 0.1;
if (alpha <= 0) {
alpha = 0;
timer.stop();
System.out.println("Morph Finished please restart.");
}
repaint();
}
public static void main(String[] args) {
JFrame theFrame = new JFrame("Testing catess...");
theFrame.setSize(400, 400);
Frame fr = new Frame();
theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theFrame.add(fr, BorderLayout.CENTER);
theFrame.setVisible(true);
}
}
答案 2 :(得分:0)
要使用JFileChooser并以用户友好的文件选择器结束,您可以这样做:
private static Frame workFrame;
public static Frame getWorkFrame() {
return workFrame;
}
public static void setWorkFrame(Frame frame) {
workFrame = frame;
}
然后按以下方式修改保存方法(签名更改,我也评论了使用扫描程序的代码并将其替换为JFileChooser)
public static void save(BufferedImage img, Frame frame) {
// Scanner scan = new Scanner(System.in);
// System.out.println("Enter the file name: ");
// String fileFullPath = scan.next();
String fileFullPath = getFileToSaveTo(frame);
file = new File(fileFullPath);
saveToFile(img, file);
}
添加以下方法:
public static String getFileToSaveTo(Frame frame) {
JFileChooser fc=new JFileChooser();
int returnVal=fc.showOpenDialog(frame);
if (returnVal == JFileChooser.APPROVE_OPTION) {
return fc.getSelectedFile().getAbsolutePath();
}
else {
return null;
}
}
在您的主要方法中有Frame.setWorkFrame(fr);
之类的调用,其中fr定义为Frame fr = new Frame();
这应该使它适用于JFileChooser。例如,这是我在main方法中调用程序的方法
public static void main(String[] args) {
JFrame theFrame = new JFrame("Testing catess...");
theFrame.setSize(400, 400);
Frame fr = new Frame();
theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theFrame.add(fr, BorderLayout.CENTER);
theFrame.setVisible(true);
Frame.setWorkFrame(fr);
}
我的测试工作正常。测试并告诉我它是否有效