gpt4 book ai didi

java - 如何逐部分绘制图像?

转载 作者:行者123 更新时间:2023-12-01 22:33:56 25 4
gpt4 key购买 nike

class DrawIma extends JPanel{
protected void paintComponent(Graphics g) {

super.paintComponent(g);
for (int i=0;i<20;i++){
for (int j=0;j<20;j++) {
g.drawImage(BuArr[i*20+j], 20*i, 20*j, 20, 20, null);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

在这部分中,BuArr是从BufferedImage中划分出的400个 block ,现在我希望它们被一一绘制,但是该方法无法单独绘制 block ,我该怎么做?

最佳答案

Swing 是单线程的,并且不是线程安全的。

这意味着您不应在 IU 线程(事件调度线程)内执行任何长时间运行或阻塞 ( Thread.sleep ) 操作。这还意味着您无法在 EDT 上下文之外更新、修改或创建 UI 元素。

相反,使用 Swing Timer以指定的时间间隔生成重复的回调并将图像的部分渲染为类似 BufferedImage 的内容,您可以通过其 paintComponent 将其绘制到组件上方法...

参见Concurrency in SwingHow to use Swing Timers了解更多详情

因为这是一个很好的消磨时间

这会生成 ListRectangles代表我想要绘制的各个 block ,然后我随机化 List并运行 Timer ,挑选最上面的Rectangle关闭List并使用 BufferedImage#getSubImage将其从主控绘制到缓冲区,缓冲区被绘制到屏幕上...

Raining Pixels

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestImage {

public static void main(String[] args) {
new TestImage();
}

public TestImage() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel {

private BufferedImage master;
private BufferedImage copy;

private List<Rectangle> blocks;

public TestPane() {
setBackground(Color.BLACK);
try {
master = ImageIO.read(new File("..."));
copy = new BufferedImage(master.getWidth(), master.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = copy.createGraphics();
AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f);
g2d.setComposite(composite);
g2d.setColor(new Color(0, 0, 0, 0));
g2d.fillRect(0, 0, master.getWidth(), master.getHeight());
g2d.dispose();

int blockSize = 40;

int width = master.getWidth();
int height = master.getHeight();

float aspect = Math.min(width, height) / (float) Math.max(width, height);

int blockHeight = blockSize;
blocks = new ArrayList<>(blockSize * 2);
for (int y = 0; y < master.getHeight(); y += blockHeight) {
if (y + blockHeight > master.getHeight()) {
blockHeight = master.getHeight() - y;
}
int blockWidth = blockSize;
for (int x = 0; x < master.getWidth(); x += blockWidth) {
if (x + blockWidth > master.getWidth()) {
blockWidth = master.getWidth() - x;
}
Rectangle block = new Rectangle(x, y, blockWidth, blockHeight);
blocks.add(block);
}
}
Collections.shuffle(blocks);
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (blocks.isEmpty()) {
((Timer) e.getSource()).stop();
} else {
Graphics2D g2d = copy.createGraphics();
Rectangle block = blocks.remove(0);
g2d.drawImage(master.getSubimage(block.x, block.y, block.width, block.height), block.x, block.y, TestPane.this);
g2d.dispose();
repaint();
}
}
});

timer.start();

} catch (IOException ex) {
ex.printStackTrace();
}
}

@Override
public Dimension getPreferredSize() {
return master == null ? new Dimension(200, 200) : new Dimension(master.getWidth(), master.getHeight());
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (copy != null) {
int x = (getWidth() - copy.getWidth()) / 2;
int y = (getHeight() - copy.getHeight()) / 2;
g2d.drawImage(copy, x, y, this);
}
g2d.dispose();
}

}

}

关于java - 如何逐部分绘制图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27163399/

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