2

プログラムを書いているのは、一部は楽しみのためであり、一部は、印刷用にカテゴリに分割したい大量のデジタル画像を処理するのに役立つためです。主なアイデアは、画像を 1 つの列に表示し、各画像の横にカテゴリ名を含む一連のチェックボックスを配置することです。必要なチェックボックスをオンにして、「go!」を押します。ボタンをクリックすると、選択したチェックボックスに応じて、写真がサブフォルダーにコピーされます。

これで、すべてがほぼ完了しました - 1 つのことを除いて。問題の写真は大きな jpg で、それぞれ約 7 ~ 8 MB で、約 700 枚あります。それらを一度にロードしようとすると、当然、すべてをロードするのに膨大な量のメモリと時間がかかります。それで、問題に対する良い解決策はありますか?私の考えは以下の2点でした。

1)一度に10枚の写真をロードし、どこかに次/前のボタンを配置します。不要な要素を追加するので、このアイデアは好きではありません。2) スクロールするとアプリケーションに新しい画像が読み込まれ、過去にスクロールした画像がアンロードされます。私はこのアイデアがとても好きです。

後者のアイデアをどのように実装できるかについて、誰かが私を正しい方向に向けることができますか? Google で関連するリンクが 1 つしか見つかりませんでしたが、それが役に立ったとは言えません。コードの一部で少し混乱しました。

4

4 に答える 4

2

サムネイルで十分な場合、この回答にはリサンプリングへの簡単なアプローチが含まれ、いくつかのトレードオフが引用されています。そうでない場合、この回答は、最近の画像を表示およびキャッシュするための一般的なアプローチの概要を示しています。

いずれの場合も、のデフォルトのBoolean レンダラー/エディターJTableですJCheckBoxCheckOne例です。

于 2012-11-25T00:10:20.767 に答える
1

あなたはすべての写真のためにthumnailsを作成しなければなりません、あなたはthumnailsを記憶に保つかもしれません。それには多くの時間がかかるかもしれません。

次に、問題の準備ができています。または、サムネイルがすべてのメモリに収まらない場合があります。その場合は、30〜40個をロードし、スクロール中にスクロール方向を検出して、次のバンチを別のスレッドにロードします。

ユーザーがスクロールするよりも読み込みが遅い場合は、そのような「まだ読み込まれていない写真」のデフォルトのプレースホルダー画像を表示します

于 2012-11-25T01:11:00.580 に答える
0

これが「一度使用して捨てる」種類のプログラムであれば、私はこの問題を解決しようとはしません。コマンドラインを使用して各画像のサムネイルを生成し、生成されたサムネイルをプログラムで使用します。700個のサムネイルをメモリに保持することは実行可能であるはずです。

それがオプションでない場合は、から始めJTableます。TableModelすべての画像をメモリにロードしなくても作成できます。あなたはただ画像数を知る必要があります。そのJTable時点で表示されている画像のみをレンダリングする必要があります。警告は、レンダラーが画像を要求した瞬間に画像をロードするのが遅すぎる可能性があることです。JTable数MBのサイズの画像をロードする必要がある場合、はスムーズに実行されないことが想像できます。しかし、これはおそらく、ワーカースレッドが読み込まれるキャッシュを使用することで解決できます。したがって、レンダラーが5番目の画像を要求した場合は、前の5つの画像と次の5つの画像もキャッシュにロードします。

また、写真をコピーして移動する場合はTableModel、ディレクトリ内の画像の数が変わるため、これが影響する可能性があることに注意してください。必ずそれを考慮してください!

于 2012-11-25T07:11:06.943 に答える
0

すべての画像を縮小して RAM の使用量を減らすことができます。たとえば、このコードはすべての画像を 200x200 に縮小します。そうすれば、100MB に 1000 個の画像を収めることができます。

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
import java.io.File;

public class Scroll extends JPanel {
    public static void main(String[] args) throws Exception {
        JFrame frame = new JFrame();
        JPanel panel = new Scroll();

        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

        for(int i = 0; i < 10; i++) {
            JPanel buttonPanel = new JPanel();
            JRadioButton b1 = new JRadioButton("button 1");
            JRadioButton b2 = new JRadioButton("button 2");
            JRadioButton b3 = new JRadioButton("button 3");
            ButtonGroup group = new ButtonGroup();
            group.add(b1);
            group.add(b2);
            group.add(b3);
            buttonPanel.add(b1);
            buttonPanel.add(b2);
            buttonPanel.add(b3);

            BufferedImage buffer = new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB);
            Graphics2D g = buffer.createGraphics();

            BufferedImage image = ImageIO.read(new File("image.jpg"));
            g.scale(buffer.getWidth()*1.0/image.getWidth(),
                    buffer.getHeight()*1.0/image.getHeight());
            g.drawImage(image, 0, 0, null);
            g.dispose();
            JLabel imageLabel = new JLabel(new ImageIcon(buffer));
            JSplitPane splitPane = new JSplitPane();
            splitPane.add(imageLabel, JSplitPane.LEFT);
            splitPane.add(buttonPanel, JSplitPane.RIGHT);
            panel.add(splitPane);
        }
        JScrollPane spane = new JScrollPane(panel);
        frame.add(spane);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,600);
        frame.setVisible(true);
    }
}

画像が表示されるときに動的にロードする場合は、ImageIcons の代わりに各画像に空の JPanel を使用し、それらの JPanel のペイント メソッドをオーバーライドする必要があります。Paint メソッドは、JPanel が表示されている場合にのみ呼び出されます。したがって、最も簡単な解決策は、ペイント メソッドで常にディスクからイメージをロードし、それを画面に描画することです。

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
import java.io.File;

public class Scroll extends JPanel {
    public static void main(String[] args) throws Exception {
        JFrame frame = new JFrame();
        JPanel panel = new Scroll();

        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

        for(int i = 0; i < 10; i++) {
            JPanel buttonPanel = new JPanel();
            JRadioButton b1 = new JRadioButton("button 1");
            JRadioButton b2 = new JRadioButton("button 2");
            JRadioButton b3 = new JRadioButton("button 3");
            ButtonGroup group = new ButtonGroup();
            group.add(b1);
            group.add(b2);
            group.add(b3);
            buttonPanel.add(b1);
            buttonPanel.add(b2);
            buttonPanel.add(b3);

            JPanel imagePanel = new JPanel() {
                {
                    BufferedImage image = ImageIO.read(new File("image.jpg"));
                    setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
                    image.flush();
                }
                @Override
                public void paint(Graphics g) {
                    try {
                        BufferedImage image = ImageIO.read(new File("image.jpg"));
                        g.drawImage(image, 0, 0, null);
                        image.flush();
                    } catch(Exception e) {
                    }
                }
            };

            JSplitPane splitPane = new JSplitPane();
            splitPane.add(imagePanel, JSplitPane.LEFT);
            splitPane.add(buttonPanel, JSplitPane.RIGHT);
            panel.add(splitPane);
        }
        JScrollPane spane = new JScrollPane(panel);
        frame.add(spane);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,600);
        frame.setVisible(true);
    }
}
于 2012-11-25T01:35:07.477 に答える