2015-12-06 8 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

«Simple» зависит от вашего определения «свечения». [Это] (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.

Я использую этот вид идеи для создания теней для прозрачной/не прямоугольной формы, для example, example и example

+0

Он работает да, но он использует слишком много времени, чтобы сделать какие-либо предложения, чтобы сделать его немного быстрее? –

+0

Blurring стоит дорого, вам следует кэшировать и повторно использовать результат, где это возможно – MadProgrammer

+0

Да, я не думал четко 48 минут назад, мне нужно всего лишь создать эффект свечения один раз, поэтому я загрузил изображение с помощью конструктора JPanel, а не таким образом все дорогой материал будет называться один раз. –

 Смежные вопросы

  • Нет связанных вопросов^_^