4

画像を領域に分割する方法はありますか (現在は JLabel ですが、必要に応じて変更できます)。
私は自分のプログラムでスイングを使用しており、その中にいくつかの三角形、星、台形を含む画像 (この例では正方形) があります (JPG、PNG などの可能性があります)。
アイデアは、ユーザーがこれらの図形の 1 つの内側をクリックし、ユーザーがクリックした領域の上に別の小さなアイコンを配置するというものです。ユーザーは複数の領域をクリックできますが、結局のところ、どの図形がクリックされたかを知る必要があります。

誰でも可能ですか?

4

2 に答える 2

8

私が作ったものを見てください:

これは、テストに使用した画像です。

元の画像

画像が分割された後:

画像分割後

そして、ここにソースがあります:

import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class Test {

    private JFrame frame;
    private JLabel[] labels;
    private static String imagePath = "c:/test.jpg";
    private final int rows = 3; //You should decide the values for rows and cols variables
    private final int cols = 3;
    private final int chunks = rows * cols;
    private final int SPACING = 10;//spacing between split images

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Test().createAndShowUI();
            }
        });
    }

    private void createAndShowUI() {
        frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        initComponents();
        frame.setResizable(false);
        frame.pack();
        frame.setVisible(true);
    }

    private void initComponents() {

        BufferedImage[] imgs = getImages();

        //set contentpane layout for grid
        frame.getContentPane().setLayout(new GridLayout(rows, cols, SPACING, SPACING));

        labels = new JLabel[imgs.length];

        //create JLabels with split images and add to frame contentPane
        for (int i = 0; i < imgs.length; i++) {
            labels[i] = new JLabel(new ImageIcon(Toolkit.getDefaultToolkit().createImage(imgs[i].getSource())));
            frame.getContentPane().add(labels[i]);
        }
    }

    private BufferedImage[] getImages() {
        File file = new File(imagePath); // I have bear.jpg in my working directory
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }
        BufferedImage image = null;
        try {
            image = ImageIO.read(fis); //reading the image file
        } catch (IOException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }
        int chunkWidth = image.getWidth() / cols; // determines the chunk width and height
        int chunkHeight = image.getHeight() / rows;
        int count = 0;
        BufferedImage imgs[] = new BufferedImage[chunks]; //Image array to hold image chunks
        for (int x = 0; x < rows; x++) {
            for (int y = 0; y < cols; y++) {
                //Initialize the image array with image chunks
                imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType());

                // draws the image chunk
                Graphics2D gr = imgs[count++].createGraphics();
                gr.drawImage(image, 0, 0, chunkWidth, chunkHeight, chunkWidth * y, chunkHeight * x, chunkWidth * y + chunkWidth, chunkHeight * x + chunkHeight, null);
                gr.dispose();
            }
        }
        return imgs;
    }
}

唯一の欠点は、画像が画面よりも大きい場合に問題が発生する可能性があるかどうかを確認していないことです。これgetScaledInstance(int x,int y, int width, in height)は、画像を使用して単純な画像サイズを変更し、チャンクに分割することで解決されます。

アップデート

申し訳ありませんが、Shapes の質問の場合は、/draw(Shape s)のメソッドを参照してください。Graphics2DGraphics

私はこれを読みました:

どの Shape オブジェクトも、レンダリングされる作図領域の部分を制限するクリッピング パスとして使用できます。クリッピング パスはGraphics2Dコンテキストの一部です。クリップ属性を設定するに Graphics2D.setClipは、使用するクリッピング パスを定義する Shape を呼び出して渡します。

u]image を形状にクリッピングする方法については、こちらを参照してください:描画領域のクリッピング

参考文献:

于 2012-09-14T15:30:23.757 に答える
4

ここここに示されている のgetSubImage()方法を使用できます。この例では も使用していますが、クリックできる に を追加できます。ボタンがそのアイコンに関する詳細を記憶する方法はいくつかあります。BufferedImageJLabelIconJButton

  • サブクラスJButton化し、適切なフィールドを追加します。
  • クライアント プロパティを親に追加しますJComponent
  • name親のプロパティを使用しますComponent
于 2012-09-14T12:17:33.043 に答える