¿Cómo deshabilitar el efecto de java.awt.Graphics.fillRect (int x, int y, int width, int height)?

Es la imagen original: enter image description here

Uso java.awt.Graphics.fillRect (int x, int y, int width, int height) para agregar un rectángulo de color en la imagen.

Graphics imageGraphics = image.createGraphics(); Color color = new Color(0,0,0,100); imageGraphics.setColor(color); imageGraphics.fillRect(0, 0, 800, 600); 

Entonces la imagen ha sido invertida y se ve así: enter image description here Después de eso, quiero borrar parcialmente el rectángulo negro transparente y mostrar la imagen original. imageGraphics.clearRect (100,100,100,100); Pero el efecto es así:

enter image description here

Cuál es mi requisito: enter image description here

Quiero saber por qué no funciona y ¿hay alguna otra manera de concretarlo?

Recuerde, pintar es destructivo. Podría ser posible utilizar AlphaComposite para lograr este resultado, pero una solución más simple podría ser una forma constructiva simple y una pintura que en su lugar.

El siguiente ejemplo crea dos Rectangles , uno ha sido el área que queremos llenar y uno ha sido el área que queremos mostrar, el segundo se resta del primero (para crear la ventana) y luego el resultado se pinta en la parte superior de la imagen

Cortado

 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.geom.Area; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class ShowArea { public static void main(String[] args) { new ShowArea(); } public ShowArea() { 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 img; public TestPane() { try { img = ImageIO.read(new File("sample.png")); Rectangle bounds = new Rectangle(0, 0, img.getWidth(), img.getHeight()); Rectangle clip = new Rectangle(150, 10, 100, 100); Area area = new Area(bounds); area.subtract(new Area(clip)); Graphics2D g2d = img.createGraphics(); g2d.setColor(Color.BLACK); g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f)); g2d.fill(area); g2d.dispose(); } catch (IOException ex) { ex.printStackTrace(); } } @Override public Dimension getPreferredSize() { return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); int x = (getWidth() - img.getWidth()) / 2; int y = (getHeight() - img.getHeight()) / 2; g2d.drawImage(img, x, y, this); g2d.dispose(); } } } 

Si estuviera haciendo algún tipo de progtwig de pintura, haría todo esto dentro del método paintComponent o de alguna manera que no paintComponent la imagen original; de lo contrario, habría destruido la imagen básica hasta que la vuelva a cargar

Otra solución podría ser tomar una copia del área original que desea conservar y volver a pintarla después, por ejemplo …

 img = ImageIO.read(new File("sample.png")); // This is the portion of the image we want to save... BufferedImage cutout = img.getSubimage(150, 10, 100, 100); // This is the area we want to paint over... Rectangle bounds = new Rectangle(0, 0, img.getWidth(), img.getHeight()); Graphics2D g2d = img.createGraphics(); g2d.setColor(Color.BLACK); // Save the current Composite so we can reset it... Composite comp = g2d.getComposite(); // Apply the composite and fill the area... g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f)); g2d.fill(area); // Reset the composite g2d.setComposite(comp); // Draw the part of the image we saved previously... g2d.drawImage(cutout, 150, 10, this); g2d.dispose(); 

No puedes hacer eso de la manera en que lo intentas.

Se puede hacer creando una Imagen Buffered llena de Color(0,0,0,200) , luego en esa imagen dibujar un rectángulo con Color de Color(0,0,0,200) y luego aplicarlo en la imagen. Recuerde que el dibujo llenoRectange no es una “operación de deshacer”: está escrito en píxeles y no se puede deshacer.

EDITAR

  Icon imageIcon = new javax.swing.ImageIcon("image.jpg"); BufferedImage mask = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR); BufferedImage image = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR); imageIcon.paintIcon(null, image.getGraphics(), 0, 0); Graphics maskGraphics = mask.getGraphics(); //drawing grey background maskGraphics.setColor(new Color(0, 0, 0, 120)); maskGraphics.fillRect(0, 0, mask.getWidth(), mask.getHeight()); //drawing black frame maskGraphics.setColor(new Color(0, 0, 0, 255)); maskGraphics.drawRect(99, 99, 301, 301); //drawing original image window maskGraphics.drawImage(image, 100, 100, 400, 400, 100, 100, 400, 400, null); //apply mask on image new ImageIcon(mask).paintIcon(null, image.getGraphics(), 0, 0); //result presentation label.setIcon(new ImageIcon(image)); 

Resultado

Sí, esto es fácilmente factible. El problema es que cualquier operación de dibujo es destructiva, lo que ves es lo que obtienes, la información que fue pintada se pierde.

Algo como esto donde guardas una subimagen, realiza la operación de pintura y luego dibuja la subimagen en la parte superior.

 public class Q23709070 { public static void main(String[] args) { JFrame frame = new JFrame(); Panel p = new Panel(); frame.getContentPane().add(p); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setVisible(true); } static class Panel extends JPanel { int w = 400; int h = 400; int x = 100; int y = 100; BufferedImage img; BufferedImage subImg; BufferedImage save; public Panel() { try { img = ImageIO.read(getClass().getResourceAsStream("0qzCf.jpg")); } catch (IOException e) { } subImg = img.getSubimage(x, y, w, h); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); Color g2dColor = g2d.getColor(); Color fillColor = new Color(0, 0, 0, 100); g2d.drawImage(img, 0, 0, null); g2d.setColor(fillColor); g2d.fillRect(0, 0, img.getWidth(), img.getHeight()); g2d.drawImage(subImg, x, y, null); g2d.setColor(g2dColor); if (save == null) { save = new BufferedImage(img.getWidth(), img.getHeight(), img.getType()); this.paint(save.getGraphics()); try { ImageIO.write(save, "jpg", new File("save.jpg")); } catch (IOException e) { } } } @Override @Transient public Dimension getPreferredSize() { return new Dimension(img.getWidth(), img.getHeight()); } } } 

Representación enter image description here

Intereting Posts