Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何根据用户操作更改图标的颜色?_Java_Image_Swing_Colors - Fatal编程技术网

Java 如何根据用户操作更改图标的颜色?

Java 如何根据用户操作更改图标的颜色?,java,image,swing,colors,Java,Image,Swing,Colors,我正在编写一个应用程序,用户可以通过选择新的颜色来改变屏幕上图像的颜色。我有一个简单的图像-仅40x40-如下所示: 我尝试过很多东西:像素替换、彩色模型、RGB过滤器等等。我搞不懂这些图像的东西。在尝试的过程中,我学习了BuffereImage,我可以将.png转换成该格式并显示在屏幕上。我可以使用像素替换将形状变成一个实心的彩色斑点,但结果很糟糕 从我收集到的信息来看,我想使用一个颜色模型或过滤器,但我被难倒了。这里有一个简单的应用程序,演示我在哪里 import java.awt.Bor

我正在编写一个应用程序,用户可以通过选择新的颜色来改变屏幕上图像的颜色。我有一个简单的图像-仅40x40-如下所示:

我尝试过很多东西:像素替换、彩色模型、RGB过滤器等等。我搞不懂这些图像的东西。在尝试的过程中,我学习了BuffereImage,我可以将.png转换成该格式并显示在屏幕上。我可以使用像素替换将形状变成一个实心的彩色斑点,但结果很糟糕

从我收集到的信息来看,我想使用一个颜色模型或过滤器,但我被难倒了。这里有一个简单的应用程序,演示我在哪里

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
(我从来没有使用过动态颜色和图像,所以我实在受不了。提前感谢您的帮助。)

编辑:这里是一个“之前”和“之后”的图像,在选择较暗的颜色后,我想要它:


也许有一个更优雅、更高效的版本,但如果您有一个BuffereImage,您可以尝试以下方法:

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());
    }
buffereImage图像;
对于(int y=0;y
也许这才是真正的问题:混合两种颜色可以通过将它们相乘来实现

编辑:

private Color multiply(Color color1,Color color2)
{
float[]color1Components=color1.getRGBComponents(null);
float[]color2Components=color2.getRGBColorComponents(null);
float[]新组件=新的float[3];
对于(int i=0;i<3;i++)
新组件[i]=颜色1组件[i]*颜色2组件[i];
返回新颜色(新组件[0]、新组件[1]、新组件[2],
颜色1成分[3]);
}

如果您事先知道所需的颜色,您可以将a与a
LookupTable一起使用。示例可在和中找到


如果没有,或者可能有帮助,如
BufferedImage

的上下文所示,您是否限制用户可以选择的颜色?你希望图像的哪些部分成为新颜色?我想他希望灰度图像的颜色作为所选颜色的某种亮度。是的,图像是灰度的,并且有2到6个灰度。我想调整所有这些阴影以反映所选的颜色。好吧,我的回答对您没有帮助吗,有什么问题吗?
setRGB()的+1
;我放大了。我试过setRGB,它改变了颜色,但结果都是单色的。正如你所说,我不知道如何将它们相乘。我需要考虑原始图像中的附加阴影。RGB颜色有三个组成部分:红色、绿色、蓝色,范围在0到255(一个字节)之间。如果将字节转换为从0.0到1.0的浮点值,则可以将每个组件相乘。对于灰度图像,每个像素的每个颜色分量都具有相同的强度,因此它充当亮度因子(0为黑色,1为白色)。我在我的答案中添加了代码来解释这一点(未经测试),希望这会有所帮助……是的,这会有所帮助。我会试试看。我不知道那里有灯光。我已经看到了对浮点、字节、“预乘”和移位的引用——这些都超出了我的理解。阅读getRGBColorComponents上的文档让事情变得很顺利。我会让你们知道结果如何。这是可行的,但我在透明度方面遇到了问题。我在图像周围得到一个大黑匣子。png是40x40,我认为它忽略了Alpha,但我还没有弄清楚如何保存它。有什么指示吗?我不知道客户会选择什么颜色-因此出现了JColorChooser对话框。我不知道这是否会改变你的建议。啊,你在创造一个编辑。您可以实现一个滴管工具,如本文所建议的,该工具在鼠标移动时显示RGB值。三个源RGB组件是
可查找
的索引;选择的RGB组件是这些索引中的新条目。
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]);
}