gpt4 book ai didi

java - 如何使用 Graphics2D 创建的形状剪辑 BufferedImage?(Java)

转载 作者:行者123 更新时间:2023-11-30 05:41:08 27 4
gpt4 key购买 nike

目前,我正在开发我的第一个 Java 应用程序,用户可以使用该应用程序浏览照片、剪切和旋转照片。我在裁剪图像时遇到问题。我想要实现的目标如下:

  • 用户点击“剪切”选项
  • 图像上出现由repaint方法调用的矩形形状
  • 通过拉伸(stretch)矩形,用户可以选择要剪切的区域
  • 当用户释放鼠标(停止拉伸(stretch)矩形)时,矩形包围的区域将被保留,图像的所有其余部分将被剪切。

目前我有几个问题:

  1. 我的图像集中在 JLabel 上,JLabel 依次添加到 JPanel 中,最后一个添加到 JFrame 中,所以现在,当我想在 JLable 上方添加一个矩形(因此它位于图片上)时,它是不可见的并且仅直接添加到 JPanel 上。
  2. 我用paintComponent绘制了一个图像,但不知道如何移动和拉伸(stretch)它并再次重新绘制矩形。

下面是我的代码部分(我希望)能够更准确地描述我的问题:

public class GraphicalUserInterface {


static JPanel background;
static JLabel labelIcon;

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new GraphicalUserInterface().go();
}
});
}


public void go() {
buildGui();
}

public void buildGui() {

frame = new JFrame("PicMove");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

BorderLayout layout = new BorderLayout();
background = new JPanel(layout);

/**To center picture on the background**/
labelIcon = new JLabel();
labelIcon.setHorizontalAlignment(JLabel.CENTER);
labelIcon.setVerticalAlignment(JLabel.CENTER);

background.add(BorderLayout.SOUTH, bottom);
background.add(BorderLayout.PAGE_START, bar);
background.add(BorderLayout.CENTER, labelIcon);
background.add(BorderLayout.EAST, chatPanel);

frame.getContentPane().add(BorderLayout.CENTER, background);
frame.setJMenuBar(menuBar);
frame.setVisible(true);
frame.setSize(1300, 1200);}


static class CutImage extends JPanel implements Runnable {
boolean clip;

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);

Graphics2D g2d = (Graphics2D) g;

if (clip) {
BasicStroke bs = new BasicStroke(50, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
10, null, 0);
g2d.setStroke(bs);
QuadCurve2D.Float qc = new QuadCurve2D.Float(20, 50, 100, 140, 460, 170);
g2d.setClip(qc);
}
BasicStroke bs = new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
10, new float[]{10}, 0);
g2d.setStroke(bs);
g2d.drawRect(260, 50, 80, 120);

}

@Override
public void run() {
CutImage cutPanel = new CutImage();
GraphicalUserInterface.background.add(cutPanel).repaint();
}
}
public class PicChanges implements Runnable{

static BufferedImage newImage;
static File [] selectedFile;
static int currentImage;



FileNameExtensionFilter filter;
JFileChooser fileChooser;

public void openPic() {
currentImage = 0;
try {
fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new java.io.File((System.getProperty("user.home"))));
filter = new FileNameExtensionFilter("*.images", "jpg", "gif", "png");
fileChooser.addChoosableFileFilter(filter);
fileChooser.setMultiSelectionEnabled(true);
int result = fileChooser.showOpenDialog(null);
if (result == JFileChooser.OPEN_DIALOG) {
selectedFile = fileChooser.getSelectedFiles();
for (File image : selectedFile) {
if ((image.isFile()) && (selectedFile.length > 0)){
newImage = ImageIO.read(selectedFile[0]);
GraphicalUserInterface.labelIcon.setIcon(new ImageIcon(
new ImageIcon(newImage).getImage().getScaledInstance(
450, 620, Image.SCALE_DEFAULT)));
} else if (result == JFileChooser.CANCEL_OPTION) {
System.out.println("No Pics Selected");
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
Thread.currentThread().interrupt();
openPic();
}

public static void nextPic() {
currentImage++;
try {
newImage = ImageIO.read(selectedFile[currentImage]);
} catch (IOException e) {
e.printStackTrace();
System.out.println("No pictures left");
System.out.println("next"+currentImage);
}
GraphicalUserInterface.labelIcon.setIcon(new ImageIcon(
new ImageIcon(newImage).getImage().getScaledInstance(
450, 620, Image.SCALE_DEFAULT)));
}

static class NextPicture implements Runnable{
@Override
public void run() {
Thread.currentThread().interrupt();
nextPic();
}
}

public static void previousPic () {
currentImage--;
try {
newImage = ImageIO.read(selectedFile[currentImage]);
} catch (IOException e) {
e.printStackTrace();
System.out.println("previous "+currentImage);
}
GraphicalUserInterface.labelIcon.setIcon(new ImageIcon(
new ImageIcon(newImage).getImage().getScaledInstance(
450, 620, Image.SCALE_DEFAULT)));
}

static class PreviousPic implements Runnable{
@Override
public void run() {
Thread.currentThread().interrupt();
previousPic();
}
}
}

我的想法是添加 MouseListeners,但是我可以将其添加到使用 Graphics2D 创建的形状中吗?我将非常感谢您的帮助:)谢谢

最佳答案

在寻找这个问题的解决方案时,我又问了两个问题(也许这对某人有帮助):

1) Why BufferedImage is not cut according to the drawn in paintComponent method rectangle(its height is calculated wrong)?

2) Repaint() method doesn't invoke paint() & paintComponent() methods one by one, only paintComponent () method is working

这进一步帮助我找到了方法。我的解决方案是创建一个单独的框架,用于在其中显示复制的 BufferedImage,并在该框架上借助 MouseListeners 绘制一个矩形。这是一段代码:

public class ImageScreenShot extends JFrame implements MouseListener, MouseMotionListener {

@Override
public Dimension getPreferredSize() {
return super.getPreferredSize();
}

private static Thread screenShotThread;

public static Thread getScreenShotThread() {
return screenShotThread;
}

public static void setScreenShotThread(Thread screenShot) {
ImageScreenShot.screenShotThread = screenShot;
}

private int drag_status = 0, c1, c2, c3, c4;

public int getC1() {
return c1;
}

public int getC2() {
return c2;
}

public int getC3() {
return c3;
}

public int getC4() {
return c4;
}

class AdditionalPanel extends JLabel {
private BufferedImage img;

public BufferedImage getImg() {
return img;
}

public AdditionalPanel(BufferedImage img) {
this.img = img;
setPreferredSize(new Dimension(2560, 1600));
getPreferredSize();
setLayout(null);
}

@Override
public Dimension getPreferredSize() {
return super.getPreferredSize();
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, null);
System.out.println("Additional panel class paint method was invoked");
}
}

public void cut() {
AdditionalPanel apanel = new AdditionalPanel(PicChanges.getNewImage());
JScrollPane scrollPane = new JScrollPane(apanel);
scrollPane.addMouseMotionListener(this);
scrollPane.addMouseListener(this);
getContentPane().add(scrollPane, BorderLayout.CENTER);
setPreferredSize(new Dimension(2560, 1600));
getPreferredSize();
pack();
setVisible(true);
}

private void draggedScreen() throws Exception {
int w = c1 - c3;
int h = c2 - c4;
w = w * -1;
h = h * -1;
Robot robot = new Robot();
BufferedImage img = robot.createScreenCapture(new Rectangle(c1, c2, w, h));
File save_path = new File("screen1.jpg");
ImageIO.write(img, "JPG", save_path);
GraphicalUserInterface.getLabelIcon().setIcon(new ImageIcon(new ImageIcon(img).getImage().getScaledInstance(img.getWidth(), img.getHeight(), Image.SCALE_SMOOTH)));
JOptionPane.showConfirmDialog(this, "Would you like to save your cropped Pic?");
System.out.println("Cropped image saved successfully.");
}

@Override
public void mouseClicked(MouseEvent arg0) {
}

@Override
public void mouseEntered(MouseEvent arg0) {
}

@Override
public void mouseExited(MouseEvent arg0) {
}

@Override
public void mousePressed(MouseEvent arg0) {
repaint();
c1 = arg0.getXOnScreen();
c2 = arg0.getYOnScreen();
System.out.println("pressed");
}

@Override
public void mouseReleased(MouseEvent arg0) {
repaint();
if (drag_status == 1) {
c3 = arg0.getXOnScreen();
c4 = arg0.getYOnScreen();
try {
repaint();
draggedScreen();
} catch (Exception e) {
e.printStackTrace();
}
}
}

@Override
public void mouseDragged(MouseEvent arg0) {
repaint();
drag_status = 1;
c3 = arg0.getXOnScreen();
c4 = arg0.getYOnScreen();
}

@Override
public void mouseMoved(MouseEvent arg0) {
}

@Override
public void paint(Graphics g) {
super.paint(g);
int w = c1 - c3;
int h = c2 - c4;
w = w * -1;
h = h * -1;
if (w < 0)
w = w * -1;
g.setColor(Color.RED);
g.drawRect(c1, c2, w, h);
System.out.println("Paint component was invoked in imagescreenshot class");
}

附注我知道添加 JFrame 不是最好的解决方案,但我仍在寻找实现它的最佳方法,因此请毫不犹豫地评论我的代码并告诉我什么是错误的或什么是好的)

关于java - 如何使用 Graphics2D 创建的形状剪辑 BufferedImage?(Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55628883/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com