gpt4 book ai didi

java - 如何绘制大型 BufferedImage 的一部分?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:42:42 26 4
gpt4 key购买 nike

我有一个 10000x10000 的 BufferedImage,我希望只将它的一部分绘制到 Canvas 上,有没有办法使用 args 来做到这一点,例如:

x, y, width, height ?

例如,drawImage(img, x, y, width, height) 会从图像中绘制一个矩形,起点为 (x, y),尺寸为 (width, height)?

编辑:

我要重新表述这个问题:

我有一个 10000x10000 的图像,我只想在屏幕上显示它的一部分,仅通过 x 和 y 偏移它的问题是,这仍然会导致延迟,因为整个图像正在渲染,只是其中的大部分关闭 Canvas 。我怎样才能基本上做到这一点,以便呈现整个图像,但我可以在不导致 Canvas 滞后的情况下滚动它?

最佳答案

I have a 10000x10000 BufferedImage and I'm looking to draw only part of it to a Canvas, is there a way to do this using args such as:

  1. 不要在 java 中使用 Canvas 进行自定义绘画。使用 JComponentJPanel 代替。它有一个很好的函数 paintComponent(Graphics g),覆盖它并用 g.drawImage(x, y, width, height, observer) 绘制你的图像;

  2. Swing 图形具有 Graphics.clipRect(int x, int y, int width, int height) 以在绘制图像之前将要绘制的区域矩形绑定(bind)到。

编辑(回应您编辑的问题):

第一种方法是使用 BufferedImage..getSubimage(x, y, width, height) 获取具有指定矩形区域的子图像。它更快。

    BufferedImage img = ImageIO.read(new File("file")); 
img = img.getSubimage(50, 50, 500, 500); // 500 x 500

此函数将为您提供一个新图像,该图像使用您指定的原始图像的 rectangle(x, y, width, height) 进行裁剪。使用返回的图像在您的组件上绘制。

教程资源: Clipping the Drawing Region


演示:用动画演示裁剪图像:

enter image description here

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import java.util.logging.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.Timer;

class MyCanvas extends JPanel implements ActionListener
{
public BufferedImage buffImg;
public Rectangle rectangle;
Random random;
long lastTimeChanged;
int dirX = 1, dirY = 1;
volatile static boolean imageLoading = true;
public MyCanvas() {
random = new Random();
rectangle = new Rectangle(50, 50, 250, 250);
lastTimeChanged = System.currentTimeMillis();
setBackground(Color.WHITE);
}


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

if(imageLoading)
{
showWaitForLoading(g);
return;
}

g.clipRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
g.drawImage(buffImg, 0, 0, getWidth(), getHeight(), this);

}


public void showWaitForLoading(Graphics g)
{
Graphics2D g2d = (Graphics2D)g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.DARK_GRAY);
g2d.fillRoundRect(getWidth()/2-100, getHeight()/2-15, 200, 30, 30, 30);
g2d.setColor(Color.WHITE);
g2d.drawString("Loading image...", getWidth()/2 - 45, getHeight()/2 + 3 );
g2d.dispose();
}

@Override
public void actionPerformed(ActionEvent e) {

long endTime = System.currentTimeMillis();
if(endTime - lastTimeChanged > 500)
{
dirX = random.nextInt(2) == 0 ? -1 : 1;
dirY = random.nextInt(2) == 0 ? -1 : 1;
lastTimeChanged = endTime;
}

if(rectangle.x < 0)dirX = 1;
else if(rectangle.x + rectangle.width > getWidth())dirX = -1;

if(rectangle.y < 0)dirY = 1;
else if(rectangle.y + rectangle.height > getHeight())dirY = -1;

rectangle.x = rectangle.x + dirX * 10;
rectangle.y = rectangle.y + dirY * 10;;

repaint();
}

}
public class CustomPainting {


public static void main(String[] args) throws IOException {

SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
final MyCanvas canvas = new MyCanvas();
JFrame frame = new JFrame();
frame.setSize(new Dimension(500, 500));
frame.add(canvas);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Timer timer = new Timer(200, canvas);
timer.start();
new Thread()
{
public void run()
{
try {
canvas.buffImg = ImageIO.read(new URL("http://images6.fanpop.com/image/photos/33400000/Cute-Panda-beautiful-pictures-33434826-500-500.jpg"));
MyCanvas.imageLoading = false;
} catch (IOException ex) {
Logger.getLogger(CustomPainting.class.getName()).log(Level.SEVERE, null, ex);
}
}
}.start();
}
});
}
}

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

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