# BufferedImage als schwarz-weiß-Bild



## Sam94 (30. Apr 2012)

Hi,
ich habe folgendes java-Programm geschrieben, das ein Bild zu einem schwarz-weiß-Bild machen sollte. Allerdings sind in dem ergebnis immernoch einige Grauwerte, die eigentlich nicht vorkommen dürften.


```
private void marchThroughImage(BufferedImage image) 
    {
        int w = image.getWidth();
        int h = image.getHeight(); 
        blackWhite = new BufferedImage(w,h, BufferedImage.TYPE_INT_RGB);
        for (int i = 0; i < h; i++) 
        {
            for (int j = 0; j < w; j++) 
            {        
                int pixel = image.getRGB(j,i);
                setPixelBlackWhite(j,i,pixel);
            }
        }
    }
  

    private void setPixelBlackWhite(int j,int i,int pixel)
    {       
        int white=125, black=132;
        
        int red = (pixel >> 16) & 0xff;
        int green = (pixel >> 8) & 0xff;
        int blue = (pixel) & 0xff;
        
        if(red>=white && green>=white && blue>=white)
        {
            blackWhite.setRGB(j,i,0xffffff);
        } else if(red<=black && green<=black && blue<=black)
        {
            blackWhite.setRGB(j,i,0x000000);
        } else {
            blackWhite.setRGB(j,i,pixel);
            System.out.println("x,: " + j +", y: " + i);
            System.out.println("rgb: " + ", " + red + ", " + green + ", " + blue);        
            System.out.println("");
        }
    }
```

weis jemand woran das liegt und wie ich das ändern kann?
Im Anhang ist das linke Bild das Ergebnis des Programms und rechts das Original


----------



## xehpuk (30. Apr 2012)

Hey,

dass da noch Grauwerte vorkommen können, ist ja recht naheliegend.
Du hast schließlich drei Verzweigungen, ergo gibt es bei der dritten Grauwerte.
Das liegt daran, dass deine beiden Bedingungen nicht gegensätzlich sind. Durch deine Konsolenausgaben wirst du das sicher schon selbst festgestellt haben.

Hier mal zwei Methoden im Angebot.
Nutzung des TYPE_BYTE_BINARY:

```
private static BufferedImage createBlackAndWhite(final BufferedImage src) {
	final BufferedImage result = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
	result.createGraphics().drawImage(src, 0, 0, null);
	return result;
}
```
Über den HSB-Farbraum überprüfen, ob ein Pixel schwarz oder weiß sein soll:

```
private static BufferedImage createBlackAndWhite(final BufferedImage src) {
	final int width = src.getWidth();
	final int height = src.getHeight();
	final BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
	for (int x = 0; x < width; x++)
		for (int y = 0; y < height; y++)
			result.setRGB(x, y, black(src.getRGB(x, y)) ? 0x000000 : 0xffffff);
	return result;
}

private static boolean black(final int rgb) {
	final int red = (rgb >> 16) & 0xff;
	final int green = (rgb >> 8) & 0xff;
	final int blue = (rgb) & 0xff;
	final float[] hsb = Color.RGBtoHSB(red, green, blue, null);
	return hsb[2] < 0.5f; // willkürlich: brightness < 50 % = Schwarz
}
```
Wie man da am geschicktesten einen Wert wählt, weiß ich nicht. So liefern die beiden Methoden jedenfalls unterschiedliche Ergebnisse.


----------



## beastofchaos (5. Mai 2012)

Wäre es auch möglich, dabei "unsichtbare" Stellen zu berücksichtigen?

"unsichtbare" Stellen erzeuge ich, wenn ich nach dieser Code-Zeile etwas zeiche:

```
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR));
```

Gruß, Thomas


PS: Funktioniert tut der Spaß z.B. bei Paint.NET
PS2: Und ginge das auch, wenn eine Stelle nur halb durchsichtigt ist (z.B. Alpha-Wert = 50)?


----------



## Jw456 (3. Feb 2022)

Ein Bild in Graustufen  Luninnanz   umwandeln.

Da musst du dir von  jedem Pixel die Farbwerte holen und sie in die Luminanz umrechnen. 
Da der Mensch  ca.  60%  Grün ,  30% Rot ,  10% Blau sieht 

Ergibt sich folgende  übliche Formel .


Luminanz:        y =   0.3•R  + 0.59•G + 0.11•B


----------

