2011-05-23 4 views
1

J'ai joué avec le remplissage d'image que I found here on Stack Overflow.Couleur différente après le remplissage de l'image

Je pense que le code n'est pas le problème. Bien que si vous en avez un meilleur je serais heureux de voir (ou même mieux si vous connaissez une bibliothèque qui a ce type de manipulations d'image).

Mon problème est qu'après avoir exécuté l'algorithme sur cette image, le casque du gars au lieu d'être vert est gris clair.

Je l'ai essayé sur un exemple stupide créé dans Paint et ça marche bien. Ainsi, je pense qu'il doit y avoir un certain réglage d'image ou quelque chose de ce genre qui change la valeur rgb que je lui ai assignée dans l'algorithme.

Avez-vous des suggestions sur ce qui devrait être défini dans le code (voir ci-dessous)?

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class FloodFillTest extends JPanel 
{ 
    private static final long serialVersionUID = 1L; 
    private BufferedImage bI; 
    public FloodFillTest() 
    { 
     try 
     { 
      this.bI = ImageIO.read(new File("images/brother.png")); 
      Color targetColor = Color.WHITE; 
      Color replacementColor = Color.GREEN; 
      System.out.println("targetColor="+targetColor+"; replacementColor="+replacementColor); 
      floodFill(125, 90, targetColor, replacementColor, bI);  
      setPreferredSize(new Dimension(bI.getWidth(), bI.getHeight())); 
      System.out.println("bI.getWidth()="+bI.getWidth()+"; bI.getHeight()="+bI.getHeight()); 
     }catch(IOException ex) 
     { 
      Logger.getLogger(FloodFillTest.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    /** 
    * Fills a color in the image with a different color. 
    * @param x x coordinate of starting point. 
    * @param y y coordinate of starting point. 
    * @param targetColor color we want to replace. 
    * @param replacementColor the color which is used as the replacement. 
    * @param image the image where we fill the color. 
    */ 
    public static void floodFill(int x, int y, Color targetColor, Color replacementColor, 
      BufferedImage image) 
    { 
     if(image.getRGB(x, y) != targetColor.getRGB()) 
      return; 
     image.setRGB(x, y, replacementColor.getRGB()); 
     System.out.println("after set image.getRGB(x,y)="+ new Color(image.getRGB(x,y)).toString()); 
     floodFill(x - 1, y, targetColor, replacementColor, image); 
     floodFill(x + 1, y, targetColor, replacementColor, image); 
     floodFill(x, y - 1, targetColor, replacementColor, image); 
     floodFill(x, y + 1, targetColor, replacementColor, image); 
    } 
    @Override 
    protected void paintComponent(Graphics g) 
    { 
     super.paintComponent(g);   
     Graphics2D g2 = (Graphics2D) g; 
     g2.drawImage(bI, 0,0, null); 
    } 

    public static void main(String[] args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      {    
       System.out.println("Color.WHITE="+Color.WHITE +"; Color.BLACK="+Color.BLACK); 
       JPanel p = new FloodFillTest(); 
       p.setBackground(Color.CYAN); 
       JPanel contentPane = new JPanel(); 
       contentPane.add(p); 
       JFrame f = new JFrame(); 
       f.setContentPane(contentPane); 
       f.setSize(800, 600); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       f.setVisible(true); 
      } 
     }); 
    } 
} 

Ceci est l'image que j'utilise dans les tests. The image I am using in tests.

+0

Je suis désolé, mais quel est le problème? Peut-être que je néglige quelque chose, mais je ne le vois pas. – Bart

+0

@Bart désolé pour cela, vous aviez tout à fait raison. Maintenant, je l'énonce clairement. Le problème est que le casque est rempli de couleur gris clair au lieu de vert comme indiqué dans le paramètre replacementColor. – Boro

+1

* setRGB * et * getRGB *, en plus d'être incroyablement lent, font aussi un * lot * de choses sous le capot, comme modifier les valeurs * r, g, b * selon les modèles de couleurs, etc. Quand je travaille avec " pixels ", j'utilise une image soutenue par un int * sous-jacent * et des entiers en lecture/écriture de/vers ce * int [] *. Ce n'est pas seulement plus rapide, mais vous pouvez aussi être sûr que vous lisez et mettez la valeur * r, g, b * que vous voulez. – SyntaxT3rr0r

Répondre

4

Vous avez une image en niveaux de gris ici. Vous ne pouvez pas utiliser la couleur verte sur une image en niveaux de gris. C'est pourquoi il apparaît comme gris clair.

Vous devez soit:

  • convertir l'image en RVB préalablement
  • assurez-vous que vous lisez/convertir l'image en RGB dans Java

La dernière option est plus sûr que ça n'échouera pas sur les images futures. Voici un code que j'ai trouvé sur le web qui est censé convertir en Grayscale. Une petite modification et vous avez ce dont vous avez besoin pour vous assurer que vous travaillez sur une image couleur:

public static BufferedImage convertToGrayscale(BufferedImage source) { 
    BufferedImageOp op = new ColorConvertOp(
     ColorSpace.getInstance(ColorSpace.CS_GRAY), null); 
    return op.filter(source, null); 
} 
+0

C'est ça. J'ai oublié l'évidence. Tout le temps je travaillais avec une image en niveaux de gris. Merci :) – Boro

+0

Pour l'instant je suis allé avec le changement de l'image à l'échelle de couleur. Mais par curiosité, comment pourrais-je utiliser le code dans mon exemple. J'essayais de l'utiliser sur l'image chargée, ou l'image après le remplissage et j'obtiens la même exception de pointeur nul 'Exception dans le fil" AWT-EventQueue-0 "java.lang.NullPointerException \t à java.awt.image.ComponentColorModel. getDataElements (ComponentColorModel.java:1538) \t à java.awt.image.BufferedImage.setRGB (BufferedImage.java:971) \t à test.FloodFillTest.floodFill (FloodFillTest.java:59) ...... ' – Boro

Questions connexes