我无法将我的图像(中间混合)保存到文件中?

时间:2015-04-16 15:02:18

标签: java eclipse

我已经尝试过关于编写/保存图像的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,根本不包含太多代码。有人可以帮忙吗?

3 个答案:

答案 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);
    }

我的测试工作正常。测试并告诉我它是否有效