2015-12-06 37 views
1

我有一個非常基本的矩形繪圖面板,但我想知道是否有一種簡單的方法來添加某種發光到矩形。添加發光到基本的Java矩形

public class Blocks extends JPanel { 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     this.setBackground(Color.BLACK); 

     for (int i = 1; i <= totalSteps; i++) { 
      g.setColor(Color.WHITE); 
      g.fillRect(100 + i*60, 260, 50, 50); 
     } 
    } 
} 
+0

「簡單」取決於你的「光暈」的定義。 [This](http://stackoverflow.com/questions/25274566/how-can-i-change-the-highlight-color-of-a-focused-jcombobox/25276658#25276658)演示了一種方法,您可以添加一個「發光」效果和任意形狀,但它不是簡單的任何手段,基本的過程是生成一個原始對象的「BufferedImage」,並以指定的顏色生成一個模糊的掩膜(你需要爲'generateGlow'方法) – MadProgrammer

回答

5

根據您想要達到的目的,生成「發光」效果有點涉及。

我使用這種方法爲透明/非矩形形狀(例如,很適合生成陰影)生成發光效果。

這個例子基本上創建了一個代表「發光」的BufferedImage,然後它生成一個「掩碼」,將原始的BufferedImage從中刪除。我這樣做,因爲它可以讓我在透明/半透明的圖像下繪製「發光」。在你的情況下,你可以跳過「掩蔽」過程,但這取決於你。

您還需要JHLabs, Image Filters的副本,因爲我不能打擾我自己能做模糊濾鏡

Glow effect

import com.jhlabs.image.GaussianFilter; 
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.GraphicsConfiguration; 
import java.awt.GraphicsEnvironment; 
import java.awt.Transparency; 
import java.awt.image.BufferedImage; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class GlowEffect { 

    public static void main(String[] args) { 
     new GlowEffect(); 
    } 

    public GlowEffect() { 
     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 { 

     public TestPane() { 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 

      int width = 50; 
      int height = 50; 
      int x = (getWidth() - width)/2; 
      int y = (getHeight() - height)/2; 

      BufferedImage img = generateGlow(width, height, 20, Color.YELLOW, 1f); 
      g2d.drawImage(img, x - ((img.getWidth() - width)/2), y - ((img.getHeight() - height)/2), this); 
      g2d.setColor(Color.WHITE); 
      g2d.fillRect(x, y, width, height); 
      g2d.dispose(); 
     } 

    } 

    public static BufferedImage generateGlow(int width, int height, int size, Color glow, float alpha) { 
     BufferedImage source = createCompatibleImage(width, height); 
     Graphics2D g2d = source.createGraphics(); 
     g2d.setColor(Color.WHITE); 
     g2d.fillRect(0, 0, width, height); 
     g2d.dispose(); 
     return generateGlow(source, size, glow, alpha); 
    } 

    public static BufferedImage generateGlow(BufferedImage imgSource, int size, Color color, float alpha) { 

     int imgWidth = (int)Math.round(imgSource.getWidth() + (size * 2.5)); 
     int imgHeight = (int)Math.round(imgSource.getHeight() + (size * 2.5)); 

     BufferedImage imgMask = createCompatibleImage(imgWidth, imgHeight); 
     Graphics2D g2 = imgMask.createGraphics(); 

     int x = Math.round((imgWidth - imgSource.getWidth())/2f); 
     int y = Math.round((imgHeight - imgSource.getHeight())/2f); 
     g2.drawImage(imgSource, x, y, null); 
     g2.dispose(); 

     BufferedImage imgGlow = generateBlur(imgMask, size, color, alpha); 

     imgGlow = applyMask(imgGlow, imgMask, AlphaComposite.DST_OUT); 

     return imgGlow; 

    } 
    public static BufferedImage generateBlur(BufferedImage imgSource, int size, Color color, float alpha) { 

     GaussianFilter filter = new GaussianFilter(size); 

     int imgWidth = imgSource.getWidth(); 
     int imgHeight = imgSource.getHeight(); 

     BufferedImage imgBlur = createCompatibleImage(imgWidth, imgHeight); 
     Graphics2D g2 = imgBlur.createGraphics(); 

     g2.drawImage(imgSource, 0, 0, null); 
     g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha)); 
     g2.setColor(color); 

     g2.fillRect(0, 0, imgSource.getWidth(), imgSource.getHeight()); 
     g2.dispose(); 

     imgBlur = filter.filter(imgBlur, null); 

     return imgBlur; 

    } 

    public static BufferedImage createCompatibleImage(int width, int height) { 
     return createCompatibleImage(width, height, Transparency.TRANSLUCENT); 
    } 

    public static BufferedImage createCompatibleImage(int width, int height, int transparency) { 
     BufferedImage image = getGraphicsConfiguration().createCompatibleImage(width, height, transparency); 
     image.coerceData(true); 
     return image; 
    } 
    public static GraphicsConfiguration getGraphicsConfiguration() { 
     return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); 
    } 

    public static BufferedImage applyMask(BufferedImage sourceImage, BufferedImage maskImage, int method) { 
     BufferedImage maskedImage = null; 
     if (sourceImage != null) { 
      int width = maskImage.getWidth(null); 
      int height = maskImage.getHeight(null); 

      maskedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 
      Graphics2D mg = maskedImage.createGraphics(); 

      int x = (width - sourceImage.getWidth(null))/2; 
      int y = (height - sourceImage.getHeight(null))/2; 

      mg.drawImage(sourceImage, x, y, null); 
      mg.setComposite(AlphaComposite.getInstance(method)); 

      mg.drawImage(maskImage, 0, 0, null); 

      mg.dispose(); 
     } 
     return maskedImage; 
    } 

} 

的基本工作流程如下這樣的事情:

  • 創建一個BufferedImage它代表您想要應用發光的形狀(這是一個不透明的圖像)
  • 基於size參數創建一個「蒙版」圖像,該圖像大於您想要生成發光效果的圖像,但其中的原始圖像塗在中央
  • 使用「蒙版」圖像來生成「模糊」圖像
  • 使用原始圖像,將其掩蓋到「模糊」圖像,以便原始圖像「模糊」圖像的「剪切」。這成爲我們發光效果的基礎
  • 繪製「發光/模糊」圖像,相應地調整x/y位置(發光效果大於原始形狀,因此我們需要調整其位置)
  • 塗料在所需位置的矩形

您需要查看Compositing Graphics以瞭解有關掩蔽過程如何工作的更多詳細信息。

我用這種想法來生成透明/無長方形陰影,爲exampleexampleexample

+0

它的工作原理是,但它使用太多的時間來提出任何建議,使其更快? –

+0

模糊是昂貴的,你應該緩存和重用結果在可能 – MadProgrammer

+0

是的,我沒有想清楚48分鐘前,我只需要產生一次發光效果,所以我用JPanel構造函數加載圖像,而不是這樣昂貴的東西將被稱爲一次。 –