Как изменить цвет значка в зависимости от действий пользователя? - PullRequest
2 голосов
/ 06 ноября 2011

Я пишу приложение, в котором пользователь может изменить цвет изображения на экране, выбрав новый цвет.У меня есть простое изображение - только 40x40 - как это: Character Head

Я пробовал много вещей: замена пикселей, ColorModel, RGBFilter и т. Д. Я не могу понять это изображение вещи.В процессе попытки я узнал о BufferedImage, и я могу получить .png в этот формат и отображается на экране.Я могу превратить форму в сплошную цветную каплю, используя замену пикселей, но результаты ужасны.

Из того, что я почерпнул, я хочу использовать ColorModel или Filter, но я в тупике.Вот простое приложение, которое демонстрирует, где я нахожусь.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;


public class ChangeImageColor {
  public static void main(String[] args) {
    final ChangeColor cc = new ChangeColor();
    java.awt.EventQueue.invokeLater( new Runnable() { @Override
      public void run() { cc.setVisible( true ); }}
    ); // invokeLater
  } // main
} // ChangeImageColor

  class ChangeColor extends JFrame {
    String  CHAR_HEAD    = "res/images/char/Head.png";
    JLabel  imageHead    = new JLabel( new ImageIcon( CHAR_HEAD ) );
    JButton buttonChoose = new JButton( "Choose Color" );

    public ChangeColor() {
      this.setSize( 200, 200 );
      this.setLayout( new BorderLayout() );

      buttonChoose.addActionListener( listenerButton );

      this.add( imageHead, BorderLayout.CENTER );
      this.add( buttonChoose, BorderLayout.SOUTH );
    } // constructor

    ActionListener listenerButton = new ActionListener() {
      @Override public void actionPerformed( ActionEvent event ) {
        Color newColor = JColorChooser.showDialog( null, "Choose Color", Color.RED );
        ImageIcon icon = new ImageIcon( CHAR_HEAD );

        System.out.println( "~" + newColor );

        // *****************
        // insert code to change color of Head.png to shades of chosen color
        // *****************

        imageHead.setIcon( icon );
      } // actionPerformed
    };

  } // class

(я никогда не работал с динамическими цветами и изображениями, так что я не справляюсь с работой. Заранее благодарен за вашу помощь.)1009 *

Редактировать: Вот изображение "до" и "после" того, что я хотел бы после выбора более темного цвета:

enter image description here enter image description here

Ответы [ 2 ]

5 голосов
/ 07 ноября 2011

Возможно, есть более элегантная и эффективная версия, но если у вас есть BufferedImage, вы можете попробовать что-то вроде:

BufferedImage image;
for(int y = 0; y < image.getHeight(); y++)
    for(int x = 0; x < image.getWidth(); x++)
    {
        Color imageColor = new Color(image.getRGB(x, y));
        //mix imageColor and desired color 
        image.setRGB(x, y, imageColor.getRGB());
    }

Может быть, это настоящая проблема: смешивание двух цветов можно сделать, умножив их...

Редактировать:

private Color multiply(Color color1, Color color2)
{
    float[] color1Components = color1.getRGBComponents(null);   
    float[] color2Components = color2.getRGBColorComponents(null);
    float[] newComponents = new float[3]; 

    for(int i = 0; i < 3; i++)
        newComponents[i] = color1Components[i] * color2Components[i];

    return new Color(newComponents[0], newComponents[1], newComponents[2],
        color1Components[3]);
}
2 голосов
/ 07 ноября 2011

Если вы знаете заранее нужные цвета, вы можете использовать LookupOp с LookupTable. Примеры можно найти в Использование Java 2D Filter Filter класса для обработки изображений и Обработка изображений с Java 2D .

Если нет, darker() или getHSBColor() может быть полезным, как показано здесь в контексте BufferedImage.

...