# Bild bearbeiten mit Transparenz (spiegeln, Farben austauschen)



## Blackhole16 (1. Jun 2012)

Liebe com,

Vorneweg schon einmal: Ich habe noch keine Erfahrung mit Bildbearbeitung in Java, ich habe das meiste hier gecopied und gepasted, versucht zu verstehen und meinen Ansprüchen anzupassen! (ich weiß, dass das kein guter Stil ist, aber ich versuche es später noch zu verstehen, jetzt möchte ich einfach nicht pro Bild (und das sind eine Menge) 32 Dateien anlegen müssen  )

Ich habe in einer Datei ein Bild, welches aus einer "Bodycolor" und einer "Changecolor" besteht. Der Hintergrund ist tranzparenz (gif).

Nun möchte im Programm das Bild verändern können, also spiegeln (vertikal) und sowohl Bodycolor als auch Changecolor austauschen. Der Body kann 2 Farben annehmen und die Changecolor 8. Somit währen es 32 verschiedene Dateien, die ich Pro Bild anlegen müsste, was ich aber nicht möchte 

Nun habe ich überlegt, dass das in Java ja auch irgendwie möglich sein sollte.

Das Farbenverändern mach ich mit:


```
BufferedImage image = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
image.getGraphics().drawImage(img, 0, 0, null);
BufferedImageOp convertOp = new LookupOp(new ColorReplaceLookupTable(BODY, Color.RED), null);
img = convertOp.filter(image, null);
image = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
image.getGraphics().drawImage(img, 0, 0, null);
convertOp = new LookupOp(new ColorReplaceLookupTable(CHANGE, Color.BLUE), null);

BufferedImage convertedImage = convertOp.filter(image, null );
```
BODY und CHANGE sind halt die Farben, welche den Farben im Urbild entsprechen.

hier noch das ColorReplaceLookupTable:

```
class ColorReplaceLookupTable extends LookupTable
{
    private Color srcColor;
    private Color dstColor;

    public ColorReplaceLookupTable(Color srcColor, Color dstColor)
    {
        super(0,1);
        this.srcColor = srcColor;
        this.dstColor = dstColor;
    }
    public int[] lookupPixel(int[] src, int[] dest)
    {
        if (src[0] == srcColor.getRed() &&
            src[1] == srcColor.getGreen() &&
            src[2] == srcColor.getBlue())
        {
            src[0] = dstColor.getRed();
            src[1] = dstColor.getGreen();
            src[2] = dstColor.getBlue();
        }
        return src;
    }
}
```

Es wird alles getauscht, läuft auch ohne Probleme, nur leider ist die Transparenz weg, stattdessen ist es schwarz...

So spiegel ich:


```
convertedImage.getGraphics().drawImage(convertedImage, convertedImage.getWidth()-1, 0, -convertedImage.getWidth(), convertedImage.getHeight(), null);
```

Das geht auch super, aber auch keine Transparenz (ich denke, dass das aber am Obigen liegt).


Meine Frage ist nun: Wie mache ich schwarz wieder transparent?

Ich habe gehört, dass es dazu in Java auch einen Alphachannel gibt, aber wie genau binde ich diesen ein? Ich wäre dankbar, wenn es für einen erklärt wird, der kaum Ahnung auf der Bildbearbeitung in Java hat und nicht unzuverstehende Stichworte.

Danke schon im Voraus,

mfg
BH16


----------



## damtre (1. Jun 2012)

Also auch wenn ich deinen Gedankengang nach deinem Post nicht ganz folgen kann, versuche ich mal ein wenig zu helfen... 

Zum Thema Transparenzwert:
Schau dir die API zur Klasse Color an.
API zur Klasse Color

Dort gibt es verschiedene Konstruktoren.
Unter anderem den hier:
*
Color(int r, int g, int b, int a)
          Creates an sRGB color with the specified red, green, blue, and alpha values in the range (0 - 255).*

Vielleicht hilft dir das ja schon mal weiter...


----------



## Network (1. Jun 2012)

Was mir auffällt ist, dass du INT_RGB verwendest bei der initialisierung des BufferedImages.
Dieser Bildtyp unterstützt keinen Alphachannel also keine Transparenz.
Ich würde dir INT_ARGB oder INT_ARGB_PRE empfehlen. (Kein merklicher  oder bedeutender Unterschied zwischen den Beiden)
Das A steht für Alpha  klar 

Gruß
Network


----------



## Blackhole16 (1. Jun 2012)

@damtre: danke, ich glaube damit kann ich etwas anfangen 

@Network: darüber bin ich schon gestolpert, wusste aber nicht, was ich damit anfangen soll  Ty

Jetzt tritt aber das problem auf, dass bei [c]public int[] lookupPixel(int[] src, int[] dest)[/c] src nur noch eine länge von 2 hat... Woran liegt das? Es kommt jetzt immer eine Arrayindexoutofboundsexception, weil ich ja src[2] prüfe, was es nicht gibt... 
Bei INT_RGB hat es eine länge von 3, jetzt nur noch von 2...

Danke schon einmal für eure Stichworte+erklärung,

mfg
BH16


----------



## bERt0r (1. Jun 2012)

Bin jetzt nicht so bewandert mit der Klasse, aber könnte es sein dass die ARGB in einen int wert geschrieben werden; nach dem Schema FF(A) FF(R) FF(G) FF(B) und du z.B. mit alpha= argb & FF000000 auf die Werte zugreifen musst.


----------



## Blackhole16 (1. Jun 2012)

damtre hat gesagt.:


> Color(int r, int g, int b, int a)
> Creates an sRGB color with the specified red, green, blue, and alpha values in the range (0 - 255).



?

deins verstehe ich nicht so ganz...

mfg
BH16


----------



## Blackhole16 (2. Jun 2012)

push


----------



## bERt0r (2. Jun 2012)

Hast du's schon so versucht wie ich gesagt habe? Ein ARGB speichert die Pixeldaten nunmal in einem einzelnen int wert und übergibt dir deshalb vielleicht auch nur einen. Den musst du dann in seine 4 bytes zerlegen die jeweils für einen Channel (A,R,G und B) stehen.


----------



## Blackhole16 (3. Jun 2012)

dein Tipp habe ich immernochnicht ganz verstanden, aber egal, ich habe jetzt doch noch etwas auf google (7.Seite) gefunden und jetzt fertig Strg+C und Strg+V gemacht  

Ich verstehe zwar noch nicht alles, aber es funktioniert. Für alle, die es auch gerne haben würden:


```
public static BufferedImage makeColorTransparent(BufferedImage im, final Color search, final Color replace) {
        ImageFilter filter = new RGBImageFilter() {
                public final int filterRGB(int x, int y, int rgb) {
                        if (rgb == search.getRGB()) {
                            return replace.getRGB();
                        } else {
                            return rgb;
                        }
                }
        };
        ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
        Image image = Toolkit.getDefaultToolkit().createImage(ip);
        BufferedImage img = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
		img.getGraphics().drawImage(image, 0, 0, null);
        return img;
    }
```

mfg
BH16


----------

