如何绘制大型BufferedImage的一部分? [英] How to draw part of a large BufferedImage?

查看:163
本文介绍了如何绘制大型BufferedImage的一部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个10000x10000 BufferedImage ,我只想把它的一部分画到 Canvas ,is有一种方法可以使用args来实现,例如:

x,y,width,height



例如,drawImage(img,x,y,width,height)将从图像中以(x,y)开始绘制矩形,维度?



编辑:



我要重申这个问题:



我有一个10000x10000的图像,我只想在屏幕上显示它的一部分,只是将它与x和y抵消的问题是,这仍然会导致整个图像滞后正在渲染,其中大部分都是在画布之外。我怎么基本上可以让整个图像呈现,但我可以滚动它,而不会导致画布滞后?

>

我有一个10000x10000的BufferedImage,我只想把一部分
画到Canvas,有没有办法使用args来做到这一点,例如:





  1. 不要在java中使用画布进行自定义绘画。改为使用 JComponent JPanel 。它有一个很好的函数 paintComponent(Graphics g),覆盖它并用 g.drawImage(x,y,width,height,观察者);


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


编辑(回应你编辑的问题): b
$ b

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

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

这个函数会为您提供一个用矩形(x,y,宽度,高度)您指定的原始图像。使用返回的图像绘制组件。



教程资源: 剪切绘图区域




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


  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;

类MyCanvas扩展JPanel实现ActionListener
{
public BufferedImage buffImg;
public矩形矩形;
随机随机;
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
保护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);



$ b 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){

end end = 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();


$ b public class CustomPainting {


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

SwingUtilities.invokeLater(new Runnable(){

@Override
public void run(){$ b $ 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 /照片/ 33400000 /可爱的熊猫,美丽的画面,33434826 -500-500.jpg));
MyCanvas.imageLoading = false;
} catch(IOException ex){
Logger.getLogger(CustomPainting.class.getName()).log(Level.SEVERE,null,ex);
}
}
} .start();
}
});
}
}


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:

x, y, width, height ?

So for example, drawImage(img, x, y, width, height) would draw a rectangle from the image starting at (x, y) and having (width, height) as the dimensions?

EDIT:

I'm going to re- word this question:

I have a 10000x10000 image and I only want to display a portion of it on the screen, the problem with just offsetting it by x and y is that this still causes lag as the entire image is being rendered, just most of it off canvas. How can I basically make it so that the entire image is rendered but I can scroll around it without causing the canvas to lag?

解决方案

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. Don't use canvas for custom painting in java. use JComponent or JPanel instead. It has a nice function paintComponent(Graphics g), override it and paint your image inside with g.drawImage(x, y, width, height, observer);

  2. Swing graphics has Graphics.clipRect(int x, int y, int width, int height) to bound the area rectangle to which you wish to draw prior to drawing the image.

Edit (In response to your edited question):

First approach is to use BufferedImage..getSubimage(x, y, width, height) to get a sub image with specified rectangle region. It is faster.

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

This function will give you a new image cropped with the rectangle(x, y, width, height) of your original image you specified. Use the returned image to draw on your component.

Tutorial resource: Clipping the Drawing Region


Demo: Demonstrating clipping Image with Animation:

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();
            }
        });
    }
}

这篇关于如何绘制大型BufferedImage的一部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆