# Pixelfarbe ablesen



## Chloroplast (15. Nov 2011)

Hallo, 
ich möchte gerne in einem Bild die pixelfarbe bestimmen (in RGB)

ich will in einem programm meine daten als bild abspeichern. am bildschirm klappt es gut, das problem ist wenn ich es einlesen will, muss ich einzelne Pixelpunkt abfragen. gibt es eine (möglichst) einfache methode in der man 3 int werte rauskriegt? anschauliches beispiel wäre schön...


----------



## Andi_CH (16. Nov 2011)

Wie machst du es denn am Bildschirm? Da musst du sicher auch Pixel auslesen - zeig doch mal ein wenig Code.


----------



## Chloroplast (16. Nov 2011)

am bildschirm kann ich es anzeigen..., aber nicht dir farbe bestimmen. also abspeicher klappt.

code will/werde ich nicht posten da sozusagen dort eine verschlüsselung erfolgt. ich kann nur sagen dass bestimmte variabeln in code umgesetzt werden und mithilfe von drawRect(pos1,pos2,1,1) jeweils ein punkt gemahlt wird und vorher mit setColor(new Color(c1, c2, c3)) die farbe festgelegt wird.

hoffe man kann mir auch ohne code von mir helfen
vllt gibts ja sowas wie getColor(int a, int b)? das mir einen RGB wert liefert. es würde auch gehen wenn mir eine methode den fatbwert als string zurückgibt (hexadecimales farbensystem) also etwa so orange=FFB200


----------



## Atze (16. Nov 2011)

Graphics (Java 2 Platform SE v1.4.2)

über Color bekommst du doch mit getRed() ... die werte.


----------



## Chloroplast (16. Nov 2011)

gibt es auch getGreen und getYellow?


----------



## Gast2 (16. Nov 2011)

Nö, aber getGreen und getBlue !


----------



## Chloroplast (17. Nov 2011)

sorry, meinte ich (klar RGB RedGreenBlue ich vollidiot). ich kann dort aber keine position angeben...
ich muss ja mit den RGB weten ein array füllen, also an jeden punkt einzeln rankommen


----------



## Atze (17. Nov 2011)

hier noch ein paar alternativen 

Get the color of a specific pixel - Real's Java How-to


----------



## Chloroplast (17. Nov 2011)

ausserdem gibt mir die methode nur die ausgewälte farbe an, ich muss in einem bild aber die pixelfarbe auslesen


----------



## Andi_CH (17. Nov 2011)

Chloroplast hat gesagt.:


> code will/werde ich nicht posten da sozusagen dort eine verschlüsselung erfolgt.



Dann hast du zwei Sachen nicht begriffen :
1. Bei einer Verschlüsselung ist der Algorihmus *niemals* geheim, sondern so öffentlich wie möglich - das bedeutet Sicherheit vor Fälschungen. Nur der verwendete Schlüssel ist geheim. Ich habe als weniger als null Vertrauen in deinen Algortihmus. (Ach nein, der Schlüssel ist doch hoffentlich nicht im code drin - ts ts ts)

2. Wollen wir hier nicht mehr als einige Zeilen Code sehen - also ein KSKB zum Zeichen, dass du überhaupt schon etwas hast.


----------



## Dow Jones (18. Nov 2011)

Chloroplast hat gesagt.:


> ausserdem gibt mir die methode nur die ausgewälte farbe an, ich muss in einem bild aber die pixelfarbe auslesen


In welcher Form hast du das Bild denn vorliegen? Nicht als BufferedImage? (dort hätte man ja gleich die Methode getRGB(int x, int y) zu verfügung um den ARGBwert eines einzelnen pixels zu erhalten).


----------



## bERt0r (18. Nov 2011)

Java BufferedImage - how to get the RGB value of each image pixel | devdaily.com
PS: Du solltest keine Punkte mahlen, Punktekaffee schmeckt grauenhaft


----------



## Chloroplast (18. Nov 2011)

für dow jones:

zum schreiben:

```
import java.awt.*;
import java.io.*;
import java.awt.image.*;
import javax.imageio.*;

public class WriteString{
	Graphics gr;
	Image offlinebild;
	int a,b,c;
	static int col[] = new int[2];
	static String input;

	public WriteString(String in){

		input=in;



		offlinebild = createImage(input.length(),1);
		gr = offlinebild.getGraphics();
		gr.clearRect(0,0,1,input.length());

		for(int c = 0 ; c<input.length(); c++){
			char ch = input.charAt(c);
			ToTreeInt(((int)ch));
			gr.setColor(new Color(col[0],col[1],100));
			gr.drawRect(c,1,1,1);
			System.out.println(col[0]+" : "+col[1]);
			System.out.println(gr.getColor()+"");

		}
		save();
	}

	public static void ToTreeInt(int in){

		col[0]=((int)(in/256));
		col[1]=(in-(255*(int)(in/256)));

	}


	public void save(){

		BufferedImage medBImage = new BufferedImage(input.length()*10,10, BufferedImage.TYPE_INT_RGB);
		medBImage.createGraphics().drawImage(offlinebild,0,0,input.length()*10,10,null);
		File f = new File("image.jpg");

		try
		{
		ImageIO.write(medBImage, "jpg", f);
		}
		catch(Exception e)
		{
		System.out.println(e);
		}
	}
}
```

zum lesen was noch nicht geht:


```
import java.awt.*;
import javax.swing.*;//nur zum test mal als JFrame gemacht
import java.io.*;
import java.awt.image.*;
import javax.imageio.*;

public class LoadString{
	Graphics gr;
	Image offlinebild;
	static int col[] = new int[2];
	static String output;

	public WriteString(){
		offlinebild = Toolkit.getDefaultToolkit().getImage("image.gif" );


		for(int c = 0 ; c<offlinebild.width; c++){
			//hier müsste der befehl stehen ich arbeite jetzt im code mit getImageColor(int, int) das mir ein intarray gibt als Synonym 
			int[] color=offlinebild.getImageColor(c,1);
			char ch = input.charAt(c);
			int col=ToInt(color[0],color[1]);
			char out=(char)col
			output=""+out;				

		}
		
	}

	public static int ToInt(int in,int in1){

			return (in*255+in1);

	}

}
```


----------



## Dow Jones (19. Nov 2011)

Der code ist leider nicht lauffähig, aber wenn ich das richtig sehe dann soll er folgendes machen

Beim Schreiben:
- einen String hernehmen
- ein (leeres) Bild erzeugen, das genauso breit ist wie der String Zeichen enthält
- den String Zeichen für Zeichen durchlaufen
   -- jedes Zeichen des Strings in einen Integerwert umwandeln
   -- den Integerwert als RGB-Wert interpretieren
   -- im Bild einen Pixel entsprechend dem RGB-Wert einfärben
- das Bild abspeichern

Beim Lesen:
- ein Bild hernehmen
- einen leeren String erzeugen
- das Bild Pixel für Pixel durchlaufen
   -- von jedem Pixel den RGB-Wert bestimmen
   -- diesen RGB-Wert als Zeichen interpretieren
   -- das Zeichen an einen String anhängen
- den String zurückgeben

Und das ganze soll vermutlich derart geschehen, das der nach dem Lesen zurückgelieferte String identisch ist mit dem beim Schreiben übergebenen String.    Das lässt sich eigentlich ziemlich direkt so wie es oben steht auch in Java übernehmen:


```
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;

 
public class StringIO{

    /**
     * takes a string, creates an image where the pixels corresponds to
     * the characters of the string and saves the image as 'image.gif'.
     * the image has the same width (in pixels) as the string has (in
     * characters). the height of the image is 1.
     * 
     * @param input 
     *   the string that is writen in form of an image
     */
    public static void writeString(String input) {

        // create an empty buffered image
        BufferedImage offlinebild = new BufferedImage(input.length(), 1, BufferedImage.TYPE_INT_RGB);
        
        // fill it with colored pixels, corresponding to our input string
        for( int x=0; x<input.length(); x++) {
            int rgb = (int)input.charAt(x);
            offlinebild.setRGB(x, 0, rgb);
        }

        // save the buffered image to disk
        try {
            File outfile = new File("image.gif");
            ImageIO.write(offlinebild, "gif", outfile);
        } catch (IOException ex) {
            // something went wrong when saving the image
            Logger.getLogger(StringIO.class.getName()).log(Level.SEVERE, null, ex);
        }

    }


    /**
     * reads the file 'image.gif' and creates a string where the characters
     * corresponds to the pixels of the image. only the first line of pixels
     * is considered. the resulting string has the same length (in characters)
     * as the image has (in in pixels).
     * 
     * @return 
     *   the string, that is created by converting the colors (of the pixels 
     *   in the first line of the image) to characters
     */
    public static String loadString() {
        
        StringBuilder sb = new StringBuilder();
        
        try {
            // read image from disk
            BufferedImage offlinebild = ImageIO.read(new File("image.gif"));
    
            // run through the pixels in x-direction
            for(int x=0; x<offlinebild.getWidth(); x++) {
                // get the rgb value of a pixel and cast it to char
                char c = (char) offlinebild.getRGB(x, 0);
                // append the char to our stringbuilder
                sb.append( c );
            }
            
        } catch (IOException ex) {
            // something went wrong when loading the image
            Logger.getLogger(StringIO.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return sb.toString();
    }
}
```

Anmerkung: Wenn dein Code mit jpgs nicht funktionierte, dann könnte das daran liegen das jpg ein verlustbehaftetes Kompressionsverfahren ist (so daß du gar keine Chance hast deinen ursprünglichen String wiederherzustellen). Mit gifs sollte es klappen, jedenfalls solange der String maximal 255 verschiedene Zeichen enthält. Besser geeignet ist PNG (oder BMP, TGA, TIFF etc, wobei Java diese aber so weit ich weiss nicht von Haus aus unterstützt). Am besten du schaust dir die Java-Implementation deines verwendeten Formats mal an und schaltest vor dem Speichern alles, was nach Verlustbehafteter Kompression aussieht, ab.


----------



## Chloroplast (19. Nov 2011)

also das abspeichern funktioniert ja schon. den rest kann ich nicht posten weil er wie gesagt teile des codes enthält (keine sorge Andi_CH, das proggram ist nur für  mich und ein paar freunde, damit werden jetzt keine hochsicheeren bankgeheimnisse mit übertragen. ausserdem bleibt ein teil der verschlüsselung anpassbar, sozusagen codewort). So wie ich das sehe müsste ich so ansprechen: 
StringIO.writeString("bla");
bzw.
String text = StringIO.loadString();

vielen dank für die antworten:applaus::toll:


----------



## Pommes9485 (20. Nov 2011)

Hast du vor einen Text in ein Bild zumalen, wobei jede Ziffer für eine Pixel/Farbe steht ?
Das habe ich auch schon mal gemacht^^


----------



## bERt0r (21. Nov 2011)

Für mich sieht das irgendwie so nach einem Steganographie verschnitt aus. Wenn der TO genauer erklären würde, was er eigentlich erreichen will könnte man vermutlich besser helfen.


----------



## Chloroplast (21. Nov 2011)

zwischen freuneden kleine, verschlüsselte nachichten zu versenden. Diese werden bei beliebiegen bildern späteram rand hinzugefügt (so das ein strich am unteren rand entsteht) das fällt voralldem bei großen bildern kaum auf. diese bilder kann man dann bei skype, facebook usw. verschicken. ausserdem braucht man um sie zu entschlüsseln das programm und einen code


----------



## Dow Jones (21. Nov 2011)

Nette Idee. Erinnert mich etwas an Videodat.


----------



## Chloroplast (21. Nov 2011)

achso, an die die sich über meine antworten ärgern weil sie etwas davon zeugen dass ich (noch) nicht soviel in java kann, ich mach das nicht beruflich, sondern als hobby, und ich bin unter 16


----------



## bERt0r (21. Nov 2011)

Ja, sowas nennt man Steganographie


----------



## Chloroplast (21. Nov 2011)

ja. nur bei anderen programmen wird der text in das bild integriert und ich weiss absolut nicht wie ich sowas hinbekommen soll


----------



## bERt0r (22. Nov 2011)

Also hier wird zumindest die Theorie ganz anschaulich dargestellt:
Steganography Techniques


----------

