Mixed color calculation in RGB

I want to be able to take two RGB-256 vectors and calculate the result of their mixture. I also want each vector to be different from the weight. I experimented with it using a Word color plate, and I saw that although some colors are mixed according to the weighted average:

0.5*red(255,0,0) + 0.5*yellow(255,255,0) = orange(255,127,0)

others do not:

0.5*yellow(255,255,0) + 0.5*blue(0,0,255) = gray (127,127,127) , not green (0,255,0)

Is there an algorithm for accurate calculation for all colors or am I forced to do this using a lookup table?

+27
colors rgb graphics
Nov 23 '10 at 12:24
source share
12 answers

The best explanation is that the RGB color model is not very clear to us. logical for a video display device (such as a monitor or TV) that knows only how to display colors by mixing different amounts of three predefined colors: red, green and blue. But this is not how you and I learned how to mix colors in elementary school.

In RGB, white is represented as (255, 255, 255), which corresponds to all-inclusive. The full value for each of the red, green, and blue color components is displayed, which creates such a high light intensity that we perceive the color as white. In contrast, the color black (0, 0, 0) is the β€œstandard” state of the display device β€” when color light is not displayed (β€œ0”), the result is black or no color.

When you completely mix yellow (255, 255, 0) and blue (0, 0, 255), you get the color represented (255, 255, 255) or white. When you multiply white by 0.5, you get a gray color, because 255 * 0.5 = 127.

This is probably an anomaly rather than anything that you get the expected result when mixing red and yellow. Red + yellow (510, 255, 0), so when you multiply this by 0.5, you get orange (255, 127, 0).

It turns out that what you and I learned in high school is really more accurately known as a subtractive color model , compared to the additive color model used by RGB. Looking at the two diagrams below, you will see the RGB color model (additive) on the left, compared to the CMYK (subtractive) color model on the right. You should immediately see the problem. Instead of using a subtractive color model, you get the desired results.

RGB Color ModelCMYK Color Model

EDIT: Of course, this is easier said than done. That is, even if you accept the CMYK color model instead of RGB (which is already difficult because the conversions from RGB to CMYK are largely device dependent and far from simple), this probably still will not satisfy the desire to mix pure blue (0 , 0, 255) with pure yellow (255, 255, 0) and green. CMYK uses cyan, magenta, and yellow as the 3 primary colors instead of red, yellow, and blue. And you have a lot of work ahead if you want to go for the implementation of the RYB color model in your chosen language.

I do not know of any such algorithm to realistically combine RGB colors. I tried in my answer to explain why this would be impossible, or at least extremely difficult. You can leave this question open for a few more days and see if anyone has any ideas, but I would go further and start looking for this table if you need to stick with the RGB model .; -)

+30
Nov 23 '10 at 12:44
source share

Based on this documentary answer and this alghoritm answer , I tried a simple color mixing interface using additive and subtractive approximations.

You must confirm that the primary colors RGB and CMYK give you secondary colors in the first response diagrams:

  • Red + Blue = Magenta (when added)
  • Yellow + Blue = Green (on subtractive)
  • etc.
 import javax.swing.*; import javax.swing.border.BevelBorder; import javax.swing.border.CompoundBorder; import javax.swing.border.LineBorder; import javax.swing.border.MatteBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Hashtable; import java.util.Vector; /** * Color Mixing alghoritms * User: alberto * Date: 29/01/13 * Time: 21:28 */ public class ColorMix { Vector<JLabel> firstMixColors; Vector<JLabel> secondMixColors; JComboBox/*<Mixer>*/ comboBox; JLabel firstMixColor; JLabel firstSel; JLabel secondSel; JLabel finalColor; public ColorMix() { firstMixColors = new Vector<JLabel>(); Vector<Mixer> mixers = new Vector<Mixer>(); mixers.add(new AdditiveMixer()); mixers.add(new SustractiveMixer()); mixers.add(new TertiaryMixer()); mixers.add(new DilutingSustractiveMixer()); comboBox = new JComboBox(new DefaultComboBoxModel(mixers)); firstMixColor = buildColorLabel(); firstSel = buildColorLabel(); secondSel = buildColorLabel(); secondMixColors = new Vector<JLabel>(); secondMixColors.add(firstSel); secondMixColors.add(secondSel); finalColor = buildColorLabel(); comboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { calculateMixes(); } }); buildGUI(); } private JLabel buildColorLabel() { JLabel label = new JLabel(); label.setOpaque(true); label.setHorizontalAlignment(SwingConstants.CENTER); label.setHorizontalTextPosition(SwingConstants.CENTER); label.setBorder(BorderFactory.createLineBorder(Color.BLACK)); label.setPreferredSize(new Dimension(100,25)); return label; } public void buildGUI() { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setTitle("Mixing colors"); frame.setLayout(new GridBagLayout()); GridBagConstraints cc = new GridBagConstraints(); cc.fill = GridBagConstraints.BOTH; cc.insets = new Insets(5, 5, 5, 5); cc.weightx = .2; cc.weighty = 1; frame.getContentPane().add(buildColorPanel(0), cc); frame.getContentPane().add(buildColorPanel(1), cc); cc.gridy = 1; JPanel firstMix = new JPanel(new GridBagLayout()); GridBagConstraints ccCol = new GridBagConstraints(); ccCol.fill = GridBagConstraints.BOTH; ccCol.insets = new Insets(5, 5, 5, 5); ccCol.weightx = 1; ccCol.weighty = 1; ccCol.gridx = 0; ccCol.gridy = 0; ccCol.gridheight = 2; firstMix.add(firstMixColor, ccCol); ccCol.fill = GridBagConstraints.HORIZONTAL; ccCol.weightx = 0.2; ccCol.weighty = 0.5; ccCol.gridx = 1; ccCol.gridy = 0; ccCol.gridheight = 1; ccCol.gridwidth = 1; firstMix.add(new JButton(new AbstractAction("Set First") { @Override public void actionPerformed(ActionEvent e) { setBackgroundToLabel(firstSel, firstMixColor.getBackground()); calculateMixes(); } }), ccCol); ccCol.gridx = 1; ccCol.gridy = 1; firstMix.add(new JButton(new AbstractAction("Set Second") { @Override public void actionPerformed(ActionEvent e) { setBackgroundToLabel(secondSel, firstMixColor.getBackground()); calculateMixes(); } }), ccCol); firstMix.setBorder(BorderFactory.createTitledBorder("Secondary Colors")); frame.getContentPane().add(firstMix, cc); cc.weightx = .6; JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints ccColor = new GridBagConstraints(); ccColor.fill = GridBagConstraints.BOTH; ccColor.insets = new Insets(5, 5, 5, 5); ccColor.weightx = 1; ccColor.weighty = 1; panel.add(firstSel, ccColor); ccColor.gridx = 1; panel.add(secondSel, ccColor); ccColor.gridx = 0; ccColor.gridy = 1; ccColor.weighty = 0; ccColor.gridwidth = 2; panel.add(finalColor, ccColor); ccColor.gridy = 2; panel.add(comboBox, ccColor); panel.setBorder(BorderFactory.createTitledBorder("Tertiary Colors")); frame.getContentPane().add(panel, cc); frame.pack(); frame.setVisible(true); } public static void main(String[] args) { new ColorMix(); } private JComponent buildColorPanel(int selectedIndex) { final JLabel pColor = buildColorLabel(); firstMixColors.add(pColor); JPanel pSelectColor = new JPanel(new GridBagLayout()); GridBagConstraints cc = new GridBagConstraints(); cc.fill = GridBagConstraints.BOTH; cc.insets = new Insets(5, 5, 5, 5); cc.weightx = 1; cc.weighty = 1; final JSlider slidRed = buildSlider(pSelectColor, cc); final JSlider slidGreen = buildSlider(pSelectColor, cc); final JSlider slidBlue = buildSlider(pSelectColor, cc); pSelectColor.add(pColor, cc); final JComboBox comboColores = buildColorCombo(); comboColores.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Color color = (Color) comboColores.getSelectedItem(); slidRed.setValue(color.getRed()); slidGreen.setValue(color.getGreen()); slidBlue.setValue(color.getBlue()); } }); comboColores.setSelectedIndex(selectedIndex); cc.gridy = 1; cc.gridwidth = 4; cc.weighty = 0; pSelectColor.add(comboColores, cc); ChangeListener changeListener = new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { setBackgroundToLabel(pColor, new Color(slidRed.getValue(), slidGreen.getValue(), slidBlue.getValue())); calculateMixes(); } }; slidRed.addChangeListener(changeListener); slidGreen.addChangeListener(changeListener); slidBlue.addChangeListener(changeListener); pSelectColor.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); changeListener.stateChanged(null); return pSelectColor; } private JComboBox buildColorCombo() { Color TRANSPARENT = new Color(0, 0, 0, 0); Vector<Color> colors = new Vector<Color>(); colors.add(new NamedColor(Color.RED, "Red")); colors.add(new NamedColor(Color.GREEN, "Green")); colors.add(new NamedColor(Color.BLUE, "Blue")); colors.add(new NamedColor(Color.YELLOW, "Yellow")); colors.add(new NamedColor(Color.MAGENTA, "Magenta")); colors.add(new NamedColor(Color.CYAN, "Cyan")); colors.add(new NamedColor(Color.WHITE, "White")); colors.add(new NamedColor(Color.LIGHT_GRAY, "Light Gray")); colors.add(new NamedColor(Color.GRAY, "Gray")); colors.add(new NamedColor(Color.DARK_GRAY, "Dark Gray")); colors.add(new NamedColor(Color.BLACK, "Black")); colors.add(new NamedColor(Color.PINK, "Pink")); colors.add(new NamedColor(Color.ORANGE, "Orange")); colors.add(new NamedColor(TRANSPARENT, "transparent")); //http://www.w3schools.com/css/css_colornames.asp colors.add(new NamedColor(new Color(0xf0f8ff), "aliceblue")); colors.add(new NamedColor(new Color(0xfaebd7), "antiquewhite")); colors.add(new NamedColor(new Color(0x00ffff), "aqua")); colors.add(new NamedColor(new Color(0x7fffd4), "aquamarine")); colors.add(new NamedColor(new Color(0xf0ffff), "azure")); colors.add(new NamedColor(new Color(0xf5f5dc), "beige")); colors.add(new NamedColor(new Color(0xffe4c4), "bisque")); colors.add(new NamedColor(new Color(0x000000), "black")); colors.add(new NamedColor(new Color(0xffebcd), "blanchedalmond")); colors.add(new NamedColor(new Color(0x0000ff), "blue")); colors.add(new NamedColor(new Color(0x8a2be2), "blueviolet")); colors.add(new NamedColor(new Color(0xa52a2a), "brown")); colors.add(new NamedColor(new Color(0xdeb887), "burlywood")); colors.add(new NamedColor(new Color(0x5f9ea0), "cadetblue")); colors.add(new NamedColor(new Color(0x7fff00), "chartreuse")); colors.add(new NamedColor(new Color(0xd2691e), "chocolate")); colors.add(new NamedColor(new Color(0xff7f50), "coral")); colors.add(new NamedColor(new Color(0x6495ed), "cornflowerblue")); colors.add(new NamedColor(new Color(0xfff8dc), "cornsilk")); colors.add(new NamedColor(new Color(0xdc143c), "crimson")); colors.add(new NamedColor(new Color(0x00ffff), "cyan")); colors.add(new NamedColor(new Color(0x00008b), "darkblue")); colors.add(new NamedColor(new Color(0x008b8b), "darkcyan")); colors.add(new NamedColor(new Color(0xb8860b), "darkgoldenrod")); colors.add(new NamedColor(new Color(0xa9a9a9), "darkgray")); colors.add(new NamedColor(new Color(0xa9a9a9), "darkgrey")); colors.add(new NamedColor(new Color(0x006400), "darkgreen")); colors.add(new NamedColor(new Color(0xbdb76b), "darkkhaki")); colors.add(new NamedColor(new Color(0x8b008b), "darkmagenta")); colors.add(new NamedColor(new Color(0x556b2f), "darkolivegreen")); colors.add(new NamedColor(new Color(0xff8c00), "darkorange")); colors.add(new NamedColor(new Color(0x9932cc), "darkorchid")); colors.add(new NamedColor(new Color(0x8b0000), "darkred")); colors.add(new NamedColor(new Color(0xe9967a), "darksalmon")); colors.add(new NamedColor(new Color(0x8fbc8f), "darkseagreen")); colors.add(new NamedColor(new Color(0x483d8b), "darkslateblue")); colors.add(new NamedColor(new Color(0x2f4f4f), "darkslategray")); colors.add(new NamedColor(new Color(0x2f4f4f), "darkslategrey")); colors.add(new NamedColor(new Color(0x00ced1), "darkturquoise")); colors.add(new NamedColor(new Color(0x9400d3), "darkviolet")); colors.add(new NamedColor(new Color(0xff1493), "deeppink")); colors.add(new NamedColor(new Color(0x00bfff), "deepskyblue")); colors.add(new NamedColor(new Color(0x696969), "dimgray")); colors.add(new NamedColor(new Color(0x696969), "dimgrey")); colors.add(new NamedColor(new Color(0x1e90ff), "dodgerblue")); colors.add(new NamedColor(new Color(0xb22222), "firebrick")); colors.add(new NamedColor(new Color(0xfffaf0), "floralwhite")); colors.add(new NamedColor(new Color(0x228b22), "forestgreen")); colors.add(new NamedColor(new Color(0xff00ff), "fuchsia")); colors.add(new NamedColor(new Color(0xdcdcdc), "gainsboro")); colors.add(new NamedColor(new Color(0xf8f8ff), "ghostwhite")); colors.add(new NamedColor(new Color(0xffd700), "gold")); colors.add(new NamedColor(new Color(0xdaa520), "goldenrod")); colors.add(new NamedColor(new Color(0x808080), "gray")); colors.add(new NamedColor(new Color(0x808080), "grey")); colors.add(new NamedColor(new Color(0x008000), "green")); colors.add(new NamedColor(new Color(0xadff2f), "greenyellow")); colors.add(new NamedColor(new Color(0xf0fff0), "honeydew")); colors.add(new NamedColor(new Color(0xff69b4), "hotpink")); colors.add(new NamedColor(new Color(0xcd5c5c), "indianred")); colors.add(new NamedColor(new Color(0x4b0082), "indigo")); colors.add(new NamedColor(new Color(0xfffff0), "ivory")); colors.add(new NamedColor(new Color(0xf0e68c), "khaki")); colors.add(new NamedColor(new Color(0xe6e6fa), "lavender")); colors.add(new NamedColor(new Color(0xfff0f5), "lavenderblush")); colors.add(new NamedColor(new Color(0x7cfc00), "lawngreen")); colors.add(new NamedColor(new Color(0xfffacd), "lemonchiffon")); colors.add(new NamedColor(new Color(0xadd8e6), "lightblue")); colors.add(new NamedColor(new Color(0xf08080), "lightcoral")); colors.add(new NamedColor(new Color(0xe0ffff), "lightcyan")); colors.add(new NamedColor(new Color(0xfafad2), "lightgoldenrodyellow")); colors.add(new NamedColor(new Color(0xd3d3d3), "lightgray")); colors.add(new NamedColor(new Color(0xd3d3d3), "lightgrey")); colors.add(new NamedColor(new Color(0x90ee90), "lightgreen")); colors.add(new NamedColor(new Color(0xffb6c1), "lightpink")); colors.add(new NamedColor(new Color(0xffa07a), "lightsalmon")); colors.add(new NamedColor(new Color(0x20b2aa), "lightseagreen")); colors.add(new NamedColor(new Color(0x87cefa), "lightskyblue")); colors.add(new NamedColor(new Color(0x778899), "lightslategray")); colors.add(new NamedColor(new Color(0x778899), "lightslategrey")); colors.add(new NamedColor(new Color(0xb0c4de), "lightsteelblue")); colors.add(new NamedColor(new Color(0xffffe0), "lightyellow")); colors.add(new NamedColor(new Color(0x00ff00), "lime")); colors.add(new NamedColor(new Color(0x32cd32), "limegreen")); colors.add(new NamedColor(new Color(0xfaf0e6), "linen")); colors.add(new NamedColor(new Color(0xff00ff), "magenta")); colors.add(new NamedColor(new Color(0x800000), "maroon")); colors.add(new NamedColor(new Color(0x66cdaa), "mediumaquamarine")); colors.add(new NamedColor(new Color(0x0000cd), "mediumblue")); colors.add(new NamedColor(new Color(0xba55d3), "mediumorchid")); colors.add(new NamedColor(new Color(0x9370d8), "mediumpurple")); colors.add(new NamedColor(new Color(0x3cb371), "mediumseagreen")); colors.add(new NamedColor(new Color(0x7b68ee), "mediumslateblue")); colors.add(new NamedColor(new Color(0x00fa9a), "mediumspringgreen")); colors.add(new NamedColor(new Color(0x48d1cc), "mediumturquoise")); colors.add(new NamedColor(new Color(0xc71585), "mediumvioletred")); colors.add(new NamedColor(new Color(0x191970), "midnightblue")); colors.add(new NamedColor(new Color(0xf5fffa), "mintcream")); colors.add(new NamedColor(new Color(0xffe4e1), "mistyrose")); colors.add(new NamedColor(new Color(0xffe4b5), "moccasin")); colors.add(new NamedColor(new Color(0xffdead), "navajowhite")); colors.add(new NamedColor(new Color(0x000080), "navy")); colors.add(new NamedColor(new Color(0xfdf5e6), "oldlace")); colors.add(new NamedColor(new Color(0x808000), "olive")); colors.add(new NamedColor(new Color(0x6b8e23), "olivedrab")); colors.add(new NamedColor(new Color(0xffa500), "orange")); colors.add(new NamedColor(new Color(0xff4500), "orangered")); colors.add(new NamedColor(new Color(0xda70d6), "orchid")); colors.add(new NamedColor(new Color(0xeee8aa), "palegoldenrod")); colors.add(new NamedColor(new Color(0x98fb98), "palegreen")); colors.add(new NamedColor(new Color(0xafeeee), "paleturquoise")); colors.add(new NamedColor(new Color(0xd87093), "palevioletred")); colors.add(new NamedColor(new Color(0xffefd5), "papayawhip")); colors.add(new NamedColor(new Color(0xffdab9), "peachpuff")); colors.add(new NamedColor(new Color(0xcd853f), "peru")); colors.add(new NamedColor(new Color(0xffc0cb), "pink")); colors.add(new NamedColor(new Color(0xdda0dd), "plum")); colors.add(new NamedColor(new Color(0xb0e0e6), "powderblue")); colors.add(new NamedColor(new Color(0x800080), "purple")); colors.add(new NamedColor(new Color(0xff0000), "red")); colors.add(new NamedColor(new Color(0xbc8f8f), "rosybrown")); colors.add(new NamedColor(new Color(0x4169e1), "royalblue")); colors.add(new NamedColor(new Color(0x8b4513), "saddlebrown")); colors.add(new NamedColor(new Color(0xfa8072), "salmon")); colors.add(new NamedColor(new Color(0xf4a460), "sandybrown")); colors.add(new NamedColor(new Color(0x2e8b57), "seagreen")); colors.add(new NamedColor(new Color(0xfff5ee), "seashell")); colors.add(new NamedColor(new Color(0xa0522d), "sienna")); colors.add(new NamedColor(new Color(0xc0c0c0), "silver")); colors.add(new NamedColor(new Color(0x87ceeb), "skyblue")); colors.add(new NamedColor(new Color(0x6a5acd), "slateblue")); colors.add(new NamedColor(new Color(0x708090), "slategray")); colors.add(new NamedColor(new Color(0x708090), "slategrey")); colors.add(new NamedColor(new Color(0xfffafa), "snow")); colors.add(new NamedColor(new Color(0x00ff7f), "springgreen")); colors.add(new NamedColor(new Color(0x4682b4), "steelblue")); colors.add(new NamedColor(new Color(0xd2b48c), "tan")); colors.add(new NamedColor(new Color(0x008080), "teal")); colors.add(new NamedColor(new Color(0xd8bfd8), "thistle")); colors.add(new NamedColor(new Color(0xff6347), "tomato")); colors.add(new NamedColor(new Color(0x40e0d0), "turquoise")); colors.add(new NamedColor(new Color(0xee82ee), "violet")); colors.add(new NamedColor(new Color(0xf5deb3), "wheat")); colors.add(new NamedColor(new Color(0xffffff), "white")); colors.add(new NamedColor(new Color(0xf5f5f5), "whitesmoke")); colors.add(new NamedColor(new Color(0xffff00), "yellow")); colors.add(new NamedColor(new Color(0x9acd32), "yellowgreen")); JComboBox comboBox = new JComboBox(new DefaultComboBoxModel(colors)); comboBox.setRenderer(new DefaultListCellRenderer() { protected Color backgroundColor = Color.BLACK; { setBorder(new CompoundBorder( new MatteBorder(2, 5, 2, 5, Color.white) , new LineBorder(Color.black))); } public Component getListCellRendererComponent(JList list, Object obj, int row, boolean sel, boolean hasFocus) { if (obj instanceof Color) backgroundColor = (Color) obj; setText(obj.toString()); return this; } public void paint(Graphics g) { setBackground(backgroundColor); super.paint(g); } }); return comboBox; } class NamedColor extends Color { private String name; NamedColor(Color color, String name) { super(color.getRed(), color.getGreen(), color.getBlue()); this.name = name; } @Override public String toString() { return name; } } private void calculateMixes() { calculateFirstMix(); calculateSecondMix(); } private void calculateFirstMix() { calculateMix(firstMixColors, firstMixColor); } private void calculateSecondMix() { calculateMix(secondMixColors, finalColor); } private void calculateMix(Vector<JLabel> mixColors, JLabel finalColor) { Color bg = ((Mixer) comboBox.getSelectedItem()).calculateMix(mixColors); setBackgroundToLabel(finalColor, bg); } private void setBackgroundToLabel(JLabel label, Color color) { label.setBackground(color); label.setText(color.getRed() + "," + color.getGreen() + "," + color.getBlue()); } interface Mixer { Color calculateMix(Vector<JLabel> colores); } /** * Implement a additive mix of colors */ static class AdditiveMixer implements Mixer { public Color calculateMix(Vector<JLabel> colores) { int red = 0; int green = 0; int blue = 0; for (int i = 0; i < colores.size(); i++) { Color background = colores.get(i).getBackground(); red += background.getRed(); green += background.getGreen(); blue += background.getBlue(); } return new Color(Math.min(255, red), Math.min(255, green), Math.min(255, blue)); } @Override public String toString() { return "Additive"; } } /** * Implement a sustractive mix of colors */ static class SustractiveMixer implements Mixer { public Color calculateMix(Vector<JLabel> colores) { int red = 1; int green = 1; int blue = 1; for (int i = 0; i < colores.size(); i++) { Color background = colores.get(i).getBackground(); red *= background.getRed(); green *= background.getGreen(); blue *= background.getBlue(); } return new Color(Math.min(255, red / 255), Math.min(255, green / 255), Math.min(255, blue / 255)); } @Override public String toString() { return "Sustractive"; } } /** * Implement a diluting/sustractive mix of colors */ static class DilutingSustractiveMixer implements Mixer { public Color calculateMix(Vector<JLabel> colores) { int red = 0; int green = 0; int blue = 0; for (int i = 0; i < colores.size(); i++) { Color background = colores.get(i).getBackground(); red += Math.pow(255 - background.getRed(), 2); green += Math.pow(255 - background.getGreen(), 2); blue += Math.pow(255 - background.getBlue(), 2); } return new Color(Math.min(255, (int)Math.sqrt(red / colores.size())), Math.min(255, (int)Math.sqrt(green / colores.size())), Math.min(255, (int)Math.sqrt(blue / colores.size()))); } @Override public String toString() { return "Diluting/Sustractive"; } } /** * Implement a diluting/sustractive mix of colors */ static class TertiaryMixer implements Mixer { public Color calculateMix(Vector<JLabel> colores) { Color background1 = colores.get(0).getBackground(); int red = background1.getRed(); int green = background1.getGreen(); int blue = background1.getBlue(); Color background2 = colores.get(1).getBackground(); red -= background2.getRed(); green -= background2.getGreen(); blue -= background2.getBlue(); return new Color(Math.min(255, background1.getRed() - (red/2)), Math.min(255, background1.getGreen() - (green/2)), background1.getBlue() - (blue/2)); } @Override public String toString() { return "Tertiary"; } } private JSlider buildSlider(JPanel container, GridBagConstraints upperCC) { JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints cc = new GridBagConstraints(); cc.fill = GridBagConstraints.BOTH; cc.insets = new Insets(5, 5, 5, 5); cc.weightx = 1; cc.weighty = 0.7; final JSlider slider = new JSlider(JSlider.VERTICAL, 0, 255, 0); slider.setFont(new Font("Serif", Font.PLAIN, 4)); Hashtable<Integer, JLabel> labels = new Hashtable<Integer, JLabel>(); labels.put(0, new JLabel("0")); labels.put(128, new JLabel("128")); labels.put(255, new JLabel("255")); panel.add(slider, cc); final JTextField field = new JTextField(); field.setEditable(false); slider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { field.setText(String.valueOf(slider.getValue())); } }); cc.gridx = 0; cc.gridy = 1; cc.weighty = 0; panel.add(field, cc); slider.setLabelTable(labels); slider.setPaintLabels(true); container.add(panel, upperCC); return slider; } } 

Color mixing interface

Basically, these operations are similar to AND logic and OR logic. (Well, not quite)

  • When alghoritm is added, colors overlap, but for each primary value there can only be 255 (logical OR operation)
  • In Substractive alghoritm, if any primary is not, the result will not have (CYAN does not have RED, YELLOW does not BLUE: you get GREEN) (Logic and operation)

Based on this, you can get tertiary colors from a combination of primary and secondary colors, so I'm doing a tiny implementation that works very well:

 NewColor.R = Color1.R - (Color1.R - Color2.R)/2 NewColor.G = Color1.G - (Color1.G - Color2.G)/2 NewColor.B = Color1.B - (Color1.B - Color2.B)/2 

There is also a dilution / substrate algorithm mentioned in the second cited answer, but I can’t say what it is based on, just added to the testing.

+3
Jan 30 '13 at 4:23
source share

Looking at Cody Gray, I think I can suggest how to combine colors. Convert color wheel to RGB:

  cyan(0, 255, 255) blue(0, 0, 255) green(0, 255, 0) magenta(255, 0, 255) red(255, 0, 0) yellow(255, 255, 0) 

Without additional complications, colors can be combined as follows: invert both colors, add them together and invert the result (ActionScript):

 sum(0, 255, 255, 255, 0, 255, "cyan + magenta ="); sum(255, 0, 0, 0, 255, 0, "red + green ="); sum(0, 0, 0, 0, 0, 0, "black + black ="); sum(0, 0, 0, 255, 255, 255, "black + white ="); function sum(c1:int, c2:int, c3:int, b1:int, b2:int, b3:int, m:String):void { c1 = 255 - c1; c2 = 255 - c2; c3 = 255 - c3; b1 = 255 - b1; b2 = 255 - b2; b3 = 255 - b3; var d1:int = c1 + b1; var d2:int = c2 + b2; var d3:int = c3 + b3; d1 = 255 - d1; d2 = 255 - d2; d3 = 255 - d3; d1 = clamp(d1); d2 = clamp(d2); d3 = clamp(d3); trace(m, d1, d2, d3); } function clamp(value:int):int { if (value < 0) return 0; if (value > 255) return 255; return value; } 

Output:

 cyan + magenta = 0 0 255 red + green = 0 0 0 black + black = 0 0 0 black + white = 0 0 0 

See if this suits you.

Edit: I'm not pretending to be physically correct, it's just an attempt to get closer. The idea of ​​a lookup table sounds crazy to me for two reasons: it depends on two arguments, so its size will be very large; and the laws of nature are usually continuous without any or rare angular cases. If you can fill out the lookup table, you need to know the algorithm - so just write a function for it.

+2
Nov 23 '10 at 14:22
source share

The REAL answer is to change the RGB color vector space to one additional, and then return it back to RGB. In this new vector space, when you add two light vectors, it takes into account the additive properties of light and our perception of color to create an additive color.

It turns out that the CIE XYZ vector space works well for this purpose.

XYZ vectors are additive in this space and mix as light sources.

See this Cree color mixing article :

 X_mix = X1 + X2 + ... Y_mix = Y1 + Y2 + ... Z_mix = Z1 + Z2 + ... 

Then you can change the base to RGB. There are many libraries for changing colors between vector spaces, and CIEXYZ is standardized and widely supported.

This method gives realistic results that satisfy most of my goals.

Read more about CIE 1931 Color Space .

+2
Jan 11 '17 at 19:11
source share

, .

RGB, RYB ( RGB). RGB RYB : http://www.insanit.net/tag/rgb-to-ryb/ ( ).

(. ). , , - , .

- RGB. RgbColor - , , :

 -(RgbColor*)mixWith:(RgbColor *)aColor { int r1, g1, b1, r2, g2, b2, r3, g3, b3, m1, m2, w1, w2, w3; //colors and maxes, white float br; // brightness of resulting color r1 = self.redVal; g1 = self.greenVal; b1 = self.blueVal; r2 = aColor.redVal; g2 = aColor.greenVal; b2 = aColor.blueVal; w1 = MIN(r1, MIN(g1, b1)); w2 = MIN(r2, MIN(g2, b2)); // remove white before mixing r1 -= w1; g1 -= w1; b1 -= w1; r2 -= w2; g2 -= w2; b2 -= w2; m1 = MAX(r1, MAX(g1, b1)); m2 = MAX(r2, MAX(g2, b2)); br = (m1+m2)/(2*255.0); r3 = (r1+r2)*br; g3 = (g1+g2)*br; b3 = (b1+b2)*br; // average whiteness and add into final color w3 = (w1+w2)/2; r3 += w3; g3 += w3; b3 += w3; [self setRedVal:[[NSNumber numberWithFloat:r3] intValue]]; [self setGreenVal:[[NSNumber numberWithFloat:g3] intValue]]; [self setBlueVal:[[NSNumber numberWithFloat:b3] intValue]]; return self; } 
+1
15 . '11 2:22
source share

Java Kubelka-Munk Theory of Reflectance RGB. Kubelka-Munk, , ​​ .

https://github.com/benjholla/ColorMixer

+1
12 . '13 19:28
source share

, , . , , :

enter image description here

  • Cyan ,
  • (.. /) , .

, :

 Yellow + (Cyan ) = Green Yellow + (Cyan + Magenta) = Gray Yellow + (Blue) = Gray 

, .

 0.5*Yellow(255,255,0) + 0.5*Cyan(0,255,255) = VeryLightLimeGreen(128,255,128) 
+1
06 . '15 21:27
source share
0
23 . '10 12:27
source share

"" RGB - , RYB, Blue .

: (255, 255, 0) () "", (0, 0, 255) RGB, RYB EQUAL . , .

RGB R'Y'B '.

- :

 R = i1*R' + j1*Y' + k1*B'; G = i2*R' + j2*Y' + k2*B'; B = i3*R' + j3*Y' + k3*B'; 

, () RGB R'Y'B.

9 (i, j, k ), 9 (3 2 ).

, , , , , , , .

- HSV YCbCr, . ( RGB RYB , RGB- > YCbCr- > RYB).

0
23 . '10 15:12
source share

, .

RGB, , , .

, . + , + .

, ( ) :

 mixed_color = color1 | color2; // Dark theme, like RGB mixing 

:

 mixed_color = color1 & color2; // Light theme, like CMY mixing 

- , ( ), .

0
02 . '15 10:01
source share

, ( ).

Damien Del Russo, , , , rgb mix. ( ) .

, , , 255... , 0-255.

( ) . , . , , ...

, , , , .

, ( python, -) n rgb:

 def rgb_mix_colors(rgb_scale, *colors): """ color mix :param rgb_scale: scale of values :param colors: list of colors (tuple of rgb values) :return: relative mix of rgb colors """ r = g = b = 0 for item in colors: try: if not isinstance(item, tuple): raise TypeError if item[0] > rgb_scale or item[1] > rgb_scale or item[2] > rgb_scale: raise ValueError except (TypeError, ValueError): print "WARNING: Value is outside range or unhandled parameter given as function argument!" else: r += item[0] # add red value from item g += item[1] # add green value from item b += item[2] # add blue value from item ratio = max(r, g, b) if ratio > rgb_scale: ratio = float(rgb_scale) / ratio r *= ratio g *= ratio b *= ratio return int(r), int(g), int(b) if __name__ == "__main__": col_list = [(512, 10, 256), (30, 120, 50), (50, 40, 512), "exception", # should raise TypeError when mixing (3800, 20, 50), # should raise ValueError when mixing (512, 10, 512)] # example with a scale defined at 1024 instead of default, providing list of tuples as params already packed as list print "2 warning messages should be displayed on the next line:" print rgb_mix_colors(1024, *col_list) print rgb_mix_colors(255, (0, 255, 0), (0, 32, 255)) 

mixing colors adding light rgb python

0
21 . '16 16:27
source share
0
09 . '17 6:14
source share



All Articles