Zapis Grafiki (JPanel) do pliku

0

Witam!
Mam problem praktyczny: mam graficzny JPanel który coś tam sobie rysuje. Chciałbym wynik rysowania zapisać do pliku (obojętne czy bmp, jpeg czy png). Próbowałem już korzystać z BufferedImage i ImageIO.write aczkolwiek wyświetla mi błąd że nie mogę skonwertować typu graphics (panel_1.getGraphics()) do BufferedImage. Funkcja do zapisu mi działa a i owszem, tylko że zapisuje czarną "kartkę" bo nie wiem jak przypisać grafikę z JPanelu do bi (jeżeli w ogóle się da). Próbowałem też coś grzebać w JFileChooser ale też bez skutków poza wywołaniem okienka z wyborem ścieżki.
Proszę o jakieś naprowadzenie, albo nazwę biblioteki która mogłaby mi pomóc.
Z góry dziękuję!

0

Może tak:

bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
panel.paint(g);
g.dispose();
...
ImageIO.write(bi,"png",file)

width i height, to rozmiary panelu.

0
 
    public void save() {
         BufferedImage bImg = new BufferedImage(this.getWidth(),this.getHeight(), BufferedImage.TYPE_INT_RGB);
            Graphics2D cg = bImg.createGraphics();
            this.paintAll(cg);
            JFileChooser jfc = new JFileChooser();
            try {
                jfc.showSaveDialog(this);
                    if (ImageIO.write(bImg, "png", jfc.getSelectedFile()))
                    {
                        System.out.println("The file was saved!");
                    }
            } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            }
}
}

Brakuje mi tylko rozszerzenia pliku. Jest jakiś łatwy sposób na w miarę proste ustawienie automatycznego rozszerzenia? Mogę ustawić miejsce zapisu, nazwę itd, wszystko działa tylko mam defaultowo brak rozszerzenia więc muszę albo pisać "test.png" jako nazwę albo otwierać za pomocą programu do przeglądu grafiki plik bez rozszerzenia ^^. Myślałem żeby użyć:

 jfc.setFileFilter(filter);

Tylko nie wiem co ustawić pod filter... jaka ma być ta składnia tam.

1

Ja robię tak

fc.setFileFilter(new FilterExt("jpg"));

FilterExt, to klasa narzędziowa. Do konstruktora można przekazać jedno rozszerzenie lub tablicę rozszerzeń.

import javax.swing.filechooser.FileFilter;
import java.io.*;

public class FilterExt extends FileFilter
{
    private String[] exts;
    private String description="";
    public FilterExt(String ext)
    {
        exts = new String[1];
        exts[0] = "."+ext.toLowerCase();
        description = "."+ext.toLowerCase();
    }
    public FilterExt(String[] ext)
    {
        exts = new String[ext.length];
        for(int i=0;i<exts.length;i++)
        {
            exts[i] = "."+ext[i].toLowerCase();
            description+="."+ext[i].toLowerCase()+(i==exts.length-1?"":",");
        }
    }
    public boolean accept(File f)
    {
        for(int i=0;i<exts.length;i++)
        {
            if(f.getName().toLowerCase().endsWith(exts[i]))
            {
                return true;
            }
        }
        return f.isDirectory();
    }
    public String getDescription()
    {
        return description;
    }
}
0

To mi dodaje tylko typ pliku ale nadal zapisuje bez rozszerzenia?

1

Ty musisz dopisać rozszerzenie (i wziąć pod uwagę, że użytkownik mógł wpisać rozszerzenie)

String nameOfFile=fc.getSelectedFile().getAbsolutePath();
if(!nameOfFile.toLowerCase().endsWith(".jpg") && !nameOfFile.toLowerCase().endsWith(".jpeg"))
{
     nameOfFile+=".jpg";
}
0

Działa! :)

public void save() {
         BufferedImage bImg = new BufferedImage(this.getWidth(),this.getHeight(), BufferedImage.TYPE_INT_RGB);
            Graphics2D cg = bImg.createGraphics();
            this.paintAll(cg);
            JFileChooser jfc = new JFileChooser();
            String[] ExtTab = {"png","jpg","jpeg","bmp"};
            for(int i = 0; i<ExtTab.length;i++){
                jfc.setFileFilter(new FilterExt(ExtTab[i]));;
            }
            jfc.showSaveDialog(this); 
            String ext = jfc.getFileFilter().getDescription();
            String ext2=ext.substring(1, ext.length());
            
            
            File file = new File (jfc.getSelectedFile()+ext);
            if(file.exists()==false){
            try {
                
                    ImageIO.write(bImg, ext2, file);

            } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            }
            }else{
                if(JOptionPane.showOptionDialog(null, "The file exists, overwrite?","Existing file",JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null)==0){
                    file.delete();
                    try {
                        
                        ImageIO.write(bImg, ext2, file);

                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                }
            }
}
}
    

Edytowałem, włącznie z nadpisywaniem plików.
jpg na jpeg zmienione :p.
Ptaszek jest, przepraszam- szukałem wcześniej czegoś w rodzaju "fiszka", "piwo" itp :D.
EDIT: teraz już chyba ok :D

1

Po kolejnym wytknięciu błędu, to już na pewno ptaszka nie dostanę.

String[] exts = {"png","jpg","jpeg","bmp"};
jfc.setFileFilter(new FilterExt(exts));

Tak jak wyżej jest dużo lepiej, opis wyświetlanych plików w oknie JFileChooser'a jest poprawny.

0

Wtedy dodaje w jednej linii wszystkie rozszerzenia, jednocześnie nie może wybrać żadnego konkretnego i u mnie nie robi zapisu :p.
private String description="";
description+="."+ext[i].toLowerCase()+(i==exts.length-1?"":",");
w rezultacie Ci wychodzi coś takiego ".bmp,.jpg,.jpeg,.png" w linii rodzaju plików do zapisu.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.