2014-05-17 9 views
7

के लिए कस्टम रंग पैलेट जेनरेट करना मुझे जूलिया सेट छवियों को रंगीन रंग रंग बनाने के लिए एक एल्गोरिदम या विधि की आवश्यकता है। भागने समय एल्गोरिथ्म का उपयोग करते समय छवि उत्पन्न करने के लिए मैं उदाहरण के लिए निम्न छवि के साथ आते हैं:जूलिया सेट

हालांकि मैं किसी तरह की जरूरत पर the Wikipedia page की तरह एक कस्टम रंग पैलेट उत्पन्न करने के लिए:

मैं इसी तरह की छवि कैसे प्राप्त करूं? इसके अलावा, जूलिया सेट के लिए किस रंग चिकनाई एल्गोरिदम का उपयोग किया जाना चाहिए?

int max_iter = 256; 
ComplexNumber constant = new ComplexNumber(cReal,cImag); 
float Saturation = 1f; 
    for(int X=0; X<WIDTH; X++) 
    { 
     for(int Y=0; Y<HEIGHT; Y++) 
     { 
      ComplexNumber oldz = new ComplexNumber(); 
      ComplexNumber newz = new ComplexNumber(2.0*(X-WIDTH/2)/(WIDTH/2), 1.33*(Y-HEIGHT/2)/(HEIGHT/2)); 
      int i; 
      for(i=0;i<max_iter; i++) 
      { 
       oldz = newz; 
       newz = newz.square(); 
       newz.add(constant); 
       if(newz.mod() > 2) 
        break; 
      } 
      float Brightness = i < max_iter ? 1f : 0; 
      float Hue = (i%256)/255.0f; 
      Color color = Color.getHSBColor((float)Hue, Saturation, Brightness); 
      img.setRGB(X,Y,color.getRGB()); 
     } 
    } 
+0

रंग सेटिंग्स का विवरण सभी आपके कोड पर निर्भर होंगे, कुछ दिखाया नहीं गया है। हम क्या देख या समझ नहीं सकते हैं, हम आपकी मदद नहीं कर सकते हैं। छवियों पर मेरे लेने पर, "चिकनाई एल्गोरिदम" के संबंध में, * कोई भी * उपयोग नहीं किया गया था। रंग परिवर्तन अलग थे। –

+0

@ होवरक्राफ्टफुलऑफेल प्रतिक्रिया भाई के लिए धन्यवाद। मैंने आवश्यक कोड जोड़ा। कृपया इसे एक नज़र दें। साथ ही, मैंने यह नहीं कहा कि छवियों ने ** चिकनाई एल्गोरिदम ** का उपयोग किया था। मैंने अभी पूछा कि जूलिया सेट के लिए कौन सा उपयोग करना है। –

उत्तर

7

इस तरह के एक रंग मानचित्रण के लिए कई संभावित दृष्टिकोण हैं:

यहाँ स्पष्टीकरण के लिए कोड का टुकड़ा है। सबसे सरल नीचे दिए गए कार्यक्रम में स्केच किया गया है।

Custom Color Maps Updated

इस स्निपेट के मुख्य initColorMap तरीका है। इसमें अंतरण करने के लिए कई इंटरपोलेशन चरण और रंगों की एक श्रृंखला होती है। स्क्रीनशॉट में, इन

  • लाल
  • लाल कर दिया गया है, हरी
  • लाल, हरे, नीले
  • लाल, पीले, हरे, सियान (प्रश्न की पहली छवि में की तरह), नीला , मैजेंटा
  • काले, नारंगी, सफेद, नीले, गहरे नीले रंग (एक रंग नक्शा प्रश्न में दूसरी छवि से के समान प्राप्त करने के प्रयास)
  • लाल, हरे, नीले, एक साइन समारोह के साथ नमूना

विधि int सरणी देता है जिसमें इंटरपोलेटेड रंगों के आरजीबी मान होते हैं। इसका उपयोग सीधे किया जा सकता है। लेकिन एक बेहतर बहुमुखी प्रतिभा के लिए, इन सरणी को ColorMap1D इंटरफ़ेस में लपेटा जाता है, जो एक विधि प्रदान करता है जो 0.0 और 1.0 के बीच किसी भी दिए गए मान के लिए आरजीबी रंग देता है।

आपके आवेदन मामले के लिए, यह शायद इस तरह इस्तेमाल किया जा सकता था:

double value = (double)iterations/maxIterations; 
int rgb = colorMap.getColor(value); 

(संपादित: निम्नलिखित विवरण और कोड अपडेट किए गए हैं और टिप्पणी में अनुरोध के आधार पर बढ़ाया गया)

इस तरह के "सामान्यीकरण" श्रेणी [0.0, 1.0] और इंटरफेस का उपयोग करके अमूर्त अक्सर फायदेमंद होता है।

प्रभाव है कि इस अमूर्त के साथ संभव हो रहे हैं का एक प्रदर्शन के रूप में:

  • ColorMaps1D#createDefault(int steps, Color ... colors): ColorMaps1D वर्ग ColorMap1D उदाहरण बना लिए कई तरीके होते हैं एक डिफ़ॉल्ट रंग नक्शा उस के साथ रंग की एक दिया अनुक्रम से अधिक interpolates बनाता है कदम की एक पूर्वनिर्धारित संख्या (रंग नक्शे के "संकल्प")
  • ColorMaps1D#create(ColorMap1D delegate, DoubleFunction<Double> function): यह विधि एक रंग नक्शा जहां getColor विधि के तर्क से पहले यह getColor विधि ओ पारित हो जाता है को देखते हुए समारोह के साथ तब्दील हो जाता है बनाता है दिए गए प्रतिनिधि एफ।

इस प्रकार, एक आसानी से एक ColorMap1D कि interpolates गैर रैखिक रंगों के बीच बना सकते हैं। कोई भी ColorMap1D कार्यान्वयन भी बना सकता है जो कई अन्य रंगीन मानचित्रों पर अंतरण करता है।

उदाहरण के तौर पर, मैंने एक रंगीन नक्शा जोड़ा है जो डिफ़ॉल्ट, सरल लाल-> ग्रीन-> ब्लू कलर मैप का उपयोग करता है, लेकिन इसे उस फ़ंक्शन के साथ एक्सेस करता है जो तर्क की साइन की गणना करता है। इस तरह, रेड-> ग्रीन-> ब्लू कलर मैप के माध्यम से कई बार "चक्र" करना संभव है।

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.GridLayout; 
import java.util.Arrays; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class ColorMapsTest 
{ 
    public static void main(String[] args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       createAndShowGUI(); 
      } 
     }); 
    } 

    private static void createAndShowGUI() 
    { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     f.getContentPane().setLayout(new GridLayout(0,1)); 

     int steps = 1024; 
     f.getContentPane().add(
      createPanel(steps, Color.RED)); 
     f.getContentPane().add(
      createPanel(steps, Color.RED, Color.GREEN)); 
     f.getContentPane().add(
      createPanel(steps, Color.RED, Color.GREEN, Color.BLUE)); 
     f.getContentPane().add(
      createPanel(steps, 
       Color.RED, Color.YELLOW, 
       Color.GREEN, Color.CYAN, 
       Color.BLUE, Color.MAGENTA)); 
     f.getContentPane().add(
      createPanel(steps, 
       Color.BLACK, Color.ORANGE, Color.WHITE, 
       Color.BLUE, new Color(0,0,128))); 


     JPanel panel = new JPanel(new BorderLayout()); 
     Color colors[] = new Color[]{ Color.RED, Color.GREEN, Color.BLUE }; 
     String info = "With sine over "+createString(colors); 
     panel.add(new JLabel(info), BorderLayout.NORTH); 
     ColorMapPanel1D colorMapPanel = 
      new ColorMapPanel1D(
       ColorMaps1D.createSine(
        ColorMaps1D.createDefault(steps, colors), Math.PI * 4)); 
     panel.add(colorMapPanel, BorderLayout.CENTER); 
     f.getContentPane().add(panel); 


     f.setSize(500, 400); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 



    private static JPanel createPanel(int steps, Color ... colors) 
    { 
     JPanel panel = new JPanel(new BorderLayout()); 
     String info = "In "+steps+" steps over "+createString(colors); 
     panel.add(new JLabel(info), BorderLayout.NORTH); 
     ColorMapPanel1D colorMapPanel = 
      new ColorMapPanel1D(ColorMaps1D.createDefault(steps, colors)); 
     panel.add(colorMapPanel, BorderLayout.CENTER); 
     return panel; 
    } 

    private static String createString(Color ... colors) 
    { 
     StringBuilder sb = new StringBuilder(); 
     for (int i=0; i<colors.length; i++) 
     { 
      sb.append(createString(colors[i])); 
      if (i < colors.length - 1) 
      { 
       sb.append(", "); 
      } 
     } 
     return sb.toString(); 
    } 
    private static String createString(Color color) 
    { 
     return "("+color.getRed()+","+color.getGreen()+","+color.getBlue()+")"; 
    } 
} 

// NOTE: This is an interface that is equivalent to the functional 
// interface in Java 8. In an environment where Java 8 is available, 
// this interface may be omitted, and the Java 8 version of this 
// interface may be used instead. 
interface DoubleFunction<R> 
{ 
    R apply(double value); 
} 



/** 
* Interface for classes that can map a single value from the range 
* [0,1] to an int that represents an RGB color 
*/ 
interface ColorMap1D 
{ 
    /** 
    * Returns an int representing the RGB color, for the given value in [0,1] 
    * 
    * @param value The value in [0,1] 
    * @return The RGB color 
    */ 
    int getColor(double value); 
} 

/** 
* Default implementation of a {@link ColorMap1D} that is backed by 
* a simple int array 
*/ 
class DefaultColorMap1D implements ColorMap1D 
{ 
    /** 
    * The backing array containing the RGB colors 
    */ 
    private final int colorMapArray[]; 

    /** 
    * Creates a color map that is backed by the given array 
    * 
    * @param colorMapArray The array containing RGB colors 
    */ 
    DefaultColorMap1D(int colorMapArray[]) 
    { 
     this.colorMapArray = colorMapArray; 
    } 

    @Override 
    public int getColor(double value) 
    { 
     double d = Math.max(0.0, Math.min(1.0, value)); 
     int i = (int)(d * (colorMapArray.length - 1)); 
     return colorMapArray[i]; 
    } 
} 


/** 
* Methods to create {@link ColorMap1D} instances 
*/ 
class ColorMaps1D 
{ 
    /** 
    * Creates a {@link ColorMap1D} that walks through the given delegate 
    * color map using a sine function with the given frequency 
    * 
    * @param delegate The delegate 
    * @param frequency The frequency 
    * @return The new {@link ColorMap1D} 
    */ 
    static ColorMap1D createSine(ColorMap1D delegate, final double frequency) 
    { 
     return create(delegate, new DoubleFunction<Double>() 
     { 
      @Override 
      public Double apply(double value) 
      { 
       return 0.5 + 0.5 * Math.sin(value * frequency); 
      } 
     }); 
    } 

    /** 
    * Creates a {@link ColorMap1D} that will convert the argument 
    * with the given function before it is looking up the color 
    * in the given delegate 
    * 
    * @param delegate The delegate {@link ColorMap1D} 
    * @param function The function for converting the argument 
    * @return The new {@link ColorMap1D} 
    */ 
    static ColorMap1D create(
     final ColorMap1D delegate, final DoubleFunction<Double> function) 
    { 
     return new ColorMap1D() 
     { 
      @Override 
      public int getColor(double value) 
      { 
       return delegate.getColor(function.apply(value)); 
      } 
     }; 
    } 


    /** 
    * Creates a new ColorMap1D that maps a value between 0.0 and 1.0 
    * (inclusive) to the specified color range, internally using the 
    * given number of steps for interpolating between the colors 
    * 
    * @param steps The number of interpolation steps 
    * @param colors The colors 
    * @return The color map 
    */ 
    static ColorMap1D createDefault(int steps, Color ... colors) 
    { 
     return new DefaultColorMap1D(initColorMap(steps, colors)); 
    } 

    /** 
    * Creates the color array which contains RGB colors as integers, 
    * interpolated through the given colors. 
    * 
    * @param steps The number of interpolation steps, and the size 
    * of the resulting array 
    * @param colors The colors for the array 
    * @return The color array 
    */ 
    static int[] initColorMap(int steps, Color ... colors) 
    { 
     int colorMap[] = new int[steps]; 
     if (colors.length == 1) 
     { 
      Arrays.fill(colorMap, colors[0].getRGB()); 
      return colorMap; 
     } 
     double colorDelta = 1.0/(colors.length - 1); 
     for (int i=0; i<steps; i++) 
     { 
      double globalRel = (double)i/(steps - 1); 
      int index0 = (int)(globalRel/colorDelta); 
      int index1 = Math.min(colors.length-1, index0 + 1); 
      double localRel = (globalRel - index0 * colorDelta)/colorDelta; 

      Color c0 = colors[index0]; 
      int r0 = c0.getRed(); 
      int g0 = c0.getGreen(); 
      int b0 = c0.getBlue(); 
      int a0 = c0.getAlpha(); 

      Color c1 = colors[index1]; 
      int r1 = c1.getRed(); 
      int g1 = c1.getGreen(); 
      int b1 = c1.getBlue(); 
      int a1 = c1.getAlpha(); 

      int dr = r1-r0; 
      int dg = g1-g0; 
      int db = b1-b0; 
      int da = a1-a0; 

      int r = (int)(r0 + localRel * dr); 
      int g = (int)(g0 + localRel * dg); 
      int b = (int)(b0 + localRel * db); 
      int a = (int)(a0 + localRel * da); 
      int rgb = 
       (a << 24) | 
       (r << 16) | 
       (g << 8) | 
       (b << 0); 
      colorMap[i] = rgb; 
     } 
     return colorMap; 
    } 

    /** 
    * Private constructor to prevent instantiation 
    */ 
    private ColorMaps1D() 
    { 
     // Private constructor to prevent instantiation 
    } 
} 


/** 
* A panel painting a {@link ColorMap1D} 
*/ 
class ColorMapPanel1D extends JPanel 
{ 
    /** 
    * The {@link ColorMap1D} that is painted 
    */ 
    private final ColorMap1D colorMap; 

    /** 
    * Creates a new panel that paints the given color map 
    * 
    * @param colorMap The {@link ColorMap1D} to be painted 
    */ 
    ColorMapPanel1D(ColorMap1D colorMap) 
    { 
     this.colorMap = colorMap; 
    } 

    @Override 
    protected void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 

     for (int x=0; x<getWidth(); x++) 
     { 
      double d = (double)x/(getWidth() - 1); 
      int rgb = colorMap.getColor(d); 
      g.setColor(new Color(rgb)); 
      g.drawLine(x, 0, x, getHeight()); 
     } 

    } 
} 

(रंग समरेखण के बारे में:। यह कुछ ऐसा है शायद एक अलग सवाल में पूछा जाना चाहिए या हो सकता है नहीं है, क्योंकि वहाँ पहले से ही है कि StackOverflow पर के बारे में कई सवाल कर रहे हैं है उदाहरण के लिए, Smooth spectrum for Mandelbrot Set rendering देखने के (या। कई अन्य))

+0

धन्यवाद भाई। आपको अभी तंत्रिका मिली है। यह वही है जो मैं हासिल करना चाहता था। मैं आपसे अनुरोध करता हूं कि कृपया विस्तृत करने के लिए कृपया दो रंगों के बीच गैर-रैखिक रूप से इंटरपोलेट करें और इसे कैसे प्राप्त किया जाए। (+1) –

+0

@AbdulFatir मैंने जवाब और कोड थोड़ा बढ़ाया। यह अब दिखाता है कि आप "साइन वक्र" फ़ंक्शन के साथ कई बार दिए गए रंग मानचित्र के माध्यम से कैसे चक्र कर सकते हैं। लेकिन आप मनमानी कार्यों का उपयोग कर सकते हैं जो सीमा [0,1] से श्रेणी में किसी अन्य मान को [0,1] – Marco13

+0

में मानते हैं यह सुंदर सुंदरता है! धन्यवाद! –