假设我TYPE_4BYTE_ABGR
在 Swing 中有一个 BufferedImage 类型,我只想绘制它的一部分。例如,我想只画左半边或一些三角形或更复杂的东西。
原因是最终图像应由我拥有的单个图像的子部分组成。
最好的方法是什么?
如果可能的话,我更愿意定义一个多边形,然后将此形状用作绘图的蒙版。
我目前的想法:复制单个图像并将所需形状之外的所有像素设置为透明,然后绘制整个图像。我认为这可能有效,但复制和所有内容可能太慢了。
编辑:
我测试了 Guillaume 的解决方案,发现它可以工作并且不会极大地减慢绘画的速度。使用剪辑导致绘制时间从 14 毫秒增加到 35 毫秒,但这些时间非常不准确。我使用了从这里分析 EDT 。这是代码。
import java.awt.AWTEvent;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
*
*/
public class ClipTilesTest {
// tile size and number of tiles in each row/column
private static int TILE_SIZE = 100;
private static int TILE_NUM = 6;
// taken from https://stackoverflow.com/questions/5541493/how-do-i-profile-the-edt-in-java-swing
public static class TimedEventQueue extends EventQueue {
@Override
protected void dispatchEvent(AWTEvent event) {
long startNano = System.nanoTime();
super.dispatchEvent(event);
long endNano = System.nanoTime();
if (endNano - startNano > 5000000) {
System.out.println(((endNano - startNano) / 1000000) + "ms : " + event);
}
}
}
private static void initUI() {
Toolkit.getDefaultToolkit().getSystemEventQueue().push(new TimedEventQueue());
// download image
BufferedImage image;
try {
image = ImageIO.read(new URL("http://download.chip.eu//ii/163859211_4b28e1e687.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
return;
}
// take out small chunk
final BufferedImage tile = image.getSubimage(0, 0, TILE_SIZE, TILE_SIZE);
JFrame frame = new JFrame();
frame.setTitle(ClipTilesTest.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// the panel containing some tiles
JPanel view = new JPanel() {
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
for (int i = 0; i < TILE_NUM; i++) {
for (int j = 0; j < TILE_NUM; j++) {
// version 1
/*
g2d.setClip(i * TILE_SIZE, j * TILE_SIZE , (i+1)*TILE_SIZE, (j+1)*TILE_SIZE);
g2d.drawImage(tile, i * TILE_SIZE, j * TILE_SIZE, null);
*/
// version 2
g2d.setClip(i * TILE_SIZE, j * TILE_SIZE , i*TILE_SIZE + TILE_SIZE/2, (j+1)*TILE_SIZE);
g2d.drawImage(tile, i * TILE_SIZE, j * TILE_SIZE, null);
g2d.setClip(i * TILE_SIZE + TILE_SIZE/2, j * TILE_SIZE , (i+1)*TILE_SIZE , (j+1)*TILE_SIZE);
g2d.drawImage(tile, i * TILE_SIZE, j * TILE_SIZE, null);
}
}
}
};
view.setPreferredSize(new Dimension(TILE_SIZE * TILE_NUM, TILE_SIZE * TILE_NUM));
// add, pack, set visible
frame.add(view);
frame.pack();
frame.setVisible(true);
// now make a repaint event, so we can start measuring
view.repaint();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ClipTilesTest.initUI();
}
});
}
}