How to draw part of a large BufferedImage?

I have 10000x10000 BufferedImage , and I am only looking for part of it for Canvas , is there a way to do this using args, for example:

x, y, width, height ?

So, for example, drawImage (img, x, y, width, height) will draw a rectangle from an image starting with (x, y) and having (width, height) as dimensions?

EDIT:

I am going to answer this question:

I have an image of 10000x10000, and I want to display part of it on the screen, the problem with shifting it to x and y is that it still causes lag, because the whole image is rendered, and most of them are canvas. How can I make it so that the entire image is rendered, but I can scroll it without causing the canvas to lag?

+6
source share
3 answers

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

  • Do not use canvas for custom painting in java. use JComponent or JPanel . It has a nice function paintComponent(Graphics g) , redefines and draws your image inside using g.drawImage(x, y, width, height, observer) ;

  • The graphics card has Graphics.clipRect(int x, int y, int width, int height) to link the rectangle of the area you want to draw to before drawing the image.

Edit (in response to your edited question):

The first approach is to use BufferedImage..getSubimage(x, y, width, height) to get an additional image with the specified area of โ€‹โ€‹the rectangle. It's 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 using the rectangle(x, y, width, height) your original image that you specified. Use the return image to paint on your component.

Tutorial Resource: Cutting a Drawing Area


Demo: Demonstrate cropping an image with animation:

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

You can scale or draw part of the image using Graphics.drawImage, as mentioned in another answer, and according to the Java documentation, BufferedImage does not require the ImageObserver argument, so you can just pass null.

http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html

However, my choice will be the cropping area of โ€‹โ€‹the image. Here is an example you can try:

 Graphics2D g = BufferedImage.getGraphics; g.setClip(x, y, width, height); g.drawImage(sx, sy, x - sx, y - sy, null ); 
0
source

Source: https://habr.com/ru/post/956765/


All Articles