setRGB [RESOLVIDO]

Agora que entendi o que vc perguntou se era diferente…
É sim:

imagem.setRGB(line, colum, newColorr.getRGB()); System.out.println("Antes" + newColorr.getRGB()); Color kkk = new Color(imagem.getRGB(line, colum)); System.out.println("Depois" + imagem.getRGB(line, colum));
Saída:
Antes-48162767
Depois-14608335

Perguntei como vc cria a variável imagem

A variável imagem é passada através de um método para ser criptografada…

private File fileimg;
Ae no filechooser:

 fileimg = fc.getSelectedFile();

Ae na hora de chamar para criptografar (filetxt é o documento de texto com o texto a ser criptografado):

new Faztudo().criptografa(filetxt,fileimg);

Ae na hora que o criptografa recebe a imagem:

public void criptografa(File filetxt, File fileimg) { System.out.println("Criptografando..."); BufferedImage imagem = null; try { imagem = ImageIO.read(fileimg); } catch (IOException e2) { e2.printStackTrace(); }

Provavelmente a imagem que você leu não tem canal alpha. O ideal mesmo é criar um BufferedImage para conter a cópia, com o canal alfa.

Ou gravar apenas nos componentes de cor RGB. Mas aí vc terá que usar 2 pixels para representar apenas 1 byte.

É… eu tava pensando em fazer para usar 2 pixels mesmo…
Mas se for para criar o BufferedImage com o canal alpha eu faço aonde? Quando eu recebo a imagem ou quando eu vou passar ela?

Na hora que você lè.

System.out.println(“Criptografando…”);

BufferedImage novaImagem = null; try { BufferedImage imagem = ImageIO.read(fileimg); novaImagem = new BufferedImage(imagem.getWidth(), imagem.getHeight(), BufferedImage.TYPE_INT_ARGB); } catch (IOException e2) { e2.printStackTrace(); }

Se você for usar 2 pixels, aí pode melhorar muito a qualidade da imagem final.

Use o seguinte esquema:

Pixel 1:

R: 2 bits
G: 1 bit
B: 1 bit

Pixel 2:
R: 2 bits
G: 1 bit
B: 1 bit

Fica virtualmente impossível perceber a diferença de duas imagens usando esse esquema.

Ah, vou fazer para gravar em 2 pixels mesmo…

Agora uma dúvida…
Eu gravo no Red e Green ou no Green e Blue?
Qual promove menos variação na cor da imagem?

Vlws !

Para extrair os valores dos 4 últimos bits de um byte:

int ch = 'B'; int lowch = B & 0x0F; //4 bits menos significativos int highch = (B & 0xF0) >> 4; //4 bits mais significativos

Aí, para sua solução ficar 100% perfeita, basta rodar compactação no texto antes de passa-lo para a imagem.
E descompactação depois de lê-lo novamente. Isso aumenta brutalmente a quantidade de caracteres que uma imagem pode conter.
:smiley:

Fikei meio confuso com o posicionamento em 2 pixels…
Tá certo os >> dos bits??

[code]
Color m = new Color(imagem.getRGB(line, colum));
int a = m.getRed();
a = a>>2;
a = a<<2;
int b = m.getGreen();
b = b>>1;
b = b<<1;
int c = m.getBlue();
c = c>>1;
c = c<<1;

Color m2 = new Color(imagem.getRGB(line+1, colum));
int a2 = m.getRed();
a2 = a2>>2;
a2 = a2<<2;
int b2 = m.getGreen();
b2 = b2>>1;
b2 = b2<<1;
int c2 = m.getBlue();
c2 = c2>>1;
c2 = c2<<1;

/////
int bits = letras[x];
bits = bits & 3;
int novoC = c | bits;

bits = letras[x];
bits = bits >>2;
bits = bits & 3;
int novoB = b | bits;

bits = letras[x];
bits = bits >>3;
bits = bits & 3;
int novoA = a | bits;

/////////////////////
bits = letras[x];
bits = bits >>5;
bits = bits & 3;
int novoC2 = c2|bits;

bits = letras[x];
bits = bits >>6;
bits = bits & 3;
int novoB2 = b2|bits;

bits = letras[x];
bits = bits >>7;
bits = bits & 3;
int novoA2 = a2 |bits;

Color newColorr = new Color(novoA,novoB,novoC,m.getAlpha());
Color newColorr2 = new Color(novoA2,novoB2,novoC2,m2.getAlpha());

imagem.setRGB(line, colum, newColorr.getRGB());
imagem.setRGB(line+1, colum, newColorr2.getRGB());[/code]

Se tiver… Para voltar não seria assim?

[code] Color m = new Color(img1gp.getRGB(0,0)); //x,c

			 int R = m.getRed();  
			 int G = m.getGreen();  
			 int B = m.getBlue();  
			 
			 Color m2 = new Color(img1gp.getRGB(1,0)); //x,c
			 int R2 = m2.getRed();
			 int G2 = m2.getGreen();
			 int B2 = m2.getBlue();

int byteValue = ((R & 3) << 3) | ((G & 3) << 2) | ((B & 3) | ((B2 & 3) << 5) | ((G2 & 3) << 6) | ((R2 & 3) << 7)); [/code]

Existe uma maneira mais fácil de simplesmente limpar bits, veja:

Color pixel1 = new Color(imagem.getRGB(line, column)); int r1 = pixel1.getRed() & 0xFC; //Limpa os dois ultimos bit. FC=1111 1100 int g1 = pixel1.getGreen() & 0xFE; //Limpa o ultimo bit. FE=1111 1110 int b1 = pixel1.getBlue() & 0xFE;

Para voltar, os bytes que forem com o bit você fará & com 1. Os que foram 2 bits vc faz & com 3. Veja os valores em binário:

1 = 00000001
3 = 00000011

Note que você simplesmente deixa 1 nas casas que você quer pegar.

Opa!
Deu certo =)

Depois que eu pego o valor do byte, tipo 69, como que eu volto ele pra letra?

Ah…
Consegui assim:

[code] public String toBinaryString(int value)
{
String str = Integer.toBinaryString((byte) value);

    StringBuilder sb = new StringBuilder();  
       
    for (int i = 0; i < 8 - str.length(); i++) {  
       sb.append("0");       
    }  
    return sb.append(str).toString();  
 } 	[/code]

Ae eu faço assim:

int i = Integer.parseInt(toBinaryString(byteValue), 2); System.out.println((char)i);

Ahh… não tinha dado certo não, foi só coincidencia! Que raivaaa!
Tentei dakele geito, e não tá indo não =[
Malz ae por tar enchendo seu saco vini! uhHAUhuAHU mas é que não sei onde to errando…

[code]
Color pixel1 = new Color(imagem.getRGB(line, colum));
int r1 = pixel1.getRed() & 0xFC;
int g1 = pixel1.getGreen() & 0xFE;
int b1 = pixel1.getBlue() & 0xFE;

			    Color pixel2 = new Color(imagem.getRGB(line+1, colum));  
			    int r2 = pixel2.getRed() & 0xFC;
			    int g2 = pixel2.getGreen() & 0xFE;
			    int b2 = pixel2.getBlue() & 0xFE;  


			/////
			int bits = letras[x]; //É a letra que vai ser criptografada
			bits = bits & 3;  
			int novoRED1 = r1 | bits; 
						 
							 
			bits = letras[x];
			bits = bits >>2;
			bits = bits & 1;
			int novoGREEN1 = g1 | bits;
						     
			bits = letras[x];
			bits = bits >>3;
			bits = bits & 1;
			int novoBLUE1 = b1 | bits;
						     
						     
			/////////////////////
			bits = letras[x];
			bits = bits >>5;
			bits = bits & 3;
			int novoRED2 = r2|bits;
						     
			bits = letras[x];
			bits = bits >>6;
			bits = bits & 1;
			int novoGREEN2 = g2|bits;
						     
			bits = letras[x];
			bits = bits >>7;
			bits = bits & 1;
			int novoBLUE2 = b2 |bits;
						     
			Color newColorr = new Color(novoRED1,novoGREEN1,novoBLUE1,pixel1.getAlpha()); 
			Color newColorr2 = new Color(novoRED2,novoGREEN2,novoBLUE2,pixel2.getAlpha());
			
			
			imagem.setRGB(line, colum, newColorr.getRGB());
			imagem.setRGB(line+1, colum, newColorr2.getRGB());[/code]

Na hora de desincriptografar, faço o inverso:

[code] Color m = new Color(img1gp.getRGB(0,0)); //x,c

			 int R = m.getRed();  
			 int G = m.getGreen();  
			 int B = m.getBlue();  
			 
			 Color m2 = new Color(img1gp.getRGB(1,0)); //x,c
			 int R2 = m2.getRed();
			 int G2 = m2.getGreen();
			 int B2 = m2.getBlue();

		    int byteValue = ((R & 3) << 3) | ((G & 1) << 2) | ((B & 1) | ((B2 & 1) << 5) | ((G2 & 1) << 6) | ((R2 & 3) << 7)); 
			System.out.println("BYTE!" + byteValue);[/code]

Mas não dá o mesmo =[

Tem que repensar em como vc tá empurrando esses bits:

int byteValue = ((R & 3) << 6) | ((G & 1) << 5) | ((B & 1) << 4) | (R & 3) << 3 | ((G2 & 1) << 1) | (B2 & 1)); 

Era isso mesmo!!!
Maneira certa:

 int byteValue = ((R & 3)) | ((G & 1) << 2) | ((B & 1) <<3 | ((R2 & 3) << 5) | ((G2 & 1) << 6) | ((B2 & 1) << 7)); 

Agora foi bizarro…

Olha a entrada:
GINASTICA VAI SER ESTENOGRAFADO EM UMA IMAGEM.

Olha a saída:
GINACDICA FAI CEB ECDENOGBAFADO EM EMA IMAGEM.

Umas letras sairam erradas…
S vira C
T vira D
V vira F
R vira B
U vira E

Mandei Criptografar o alfabeto…

Entrada:
ABCDEFGHIJKLMNOPQRSTUVWXYZ,.?

Saída:
ABCDEFGHIJKLMNO@ABCDEFGHIJ,./l

Axo que o erro é quando eu faço isso:

String str = Integer.toBinaryString((byte) byteValue);
int i = Integer.parseInt(str, 2);
System.out.println((char) i);

O Alfabeto Criptografado Antes:

Entrada:
ABCDEFGHIJKLMNOPQRSTUVWXYZ,.?

Saída:
ABCDEFGHIJKLMNO@ABCDEFGHIJ,./l

Ae fikei encabulado…
Só a partir do “P” que tá errado?!?!

Ae colokei só o P para criptografar (letras[x] é o ‘P’)

[code] int bits = letras[x];
bits = bits & 3;
int novoRED1 = r1 | bits;

			bits = letras[x];
			bits = bits >>2;
			bits = bits & 1;
			int novoGREEN1 = g1 | bits;
						     
			bits = letras[x];
			bits = bits >>3;
			bits = bits & 1;
			int novoBLUE1 = b1 | bits;
						     
						     
			/////////////////////
			bits = letras[x];
			bits = bits >>5;
			bits = bits & 3;
			int novoRED2 = r2|bits;
						     
			bits = letras[x];
			bits = bits >>6;
			bits = bits & 1;
			int novoGREEN2 = g2|bits;
						     
			bits = letras[x];
			bits = bits >>7;
			bits = bits & 1;
			int novoBLUE2 = b2 |bits;

//PRESTEM ATENÇÃO AKI! ! ! ! ! !
int byteValueAntes = letras[x];
System.out.println("ByTE ANTES! ! " + byteValueAntes);

int byteValue= ((novoRED1 & 3)) | ((novoGREEN1 & 1) << 2) | ((novoBLUE1 & 1) <<3 | ((novoRED2 & 3) << 5) | ((novoGREEN2 & 1) << 6) | ((novoBLUE2 & 1) << 7));
System.out.println("ByTE ! ! " + byteValue);
[/code]

A saída foi:
[color=red]ByTE ANTES! ! 80
ByTE ! ! 64[/color]
Eu vi e revi… É realmente o inverso que estou fazendo…

Ele está igualando o
Q no A: “01010001” no “01000001”
R no B: “01010010” no “01000010”
S no C: “01010011” no “01000011”
Está ocorrendo a perda desses 2 bits do meio…

Consegui…

bits = letras[x]; bits = bits >>4; //EM VEZ DE 5 bits = bits & 3; int novoRED2 = r2|bits; //E na hora de voltar <<4!

Agora tá dando tudo certo… Menos uma coisa:
Posso colocar qualquer texto lá…
Mas ele não reconhece coisas como à á â ã , etc…
Porque será?