package so;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class App {
public static void main(String[] args) {
System.out.println(decode1(toChannelLastBits(readImage("MBlXyTSp.png"))));
showImage(decode2(toChannelLastBits(readImage("mCeETXDs.png"))));
}
private static BufferedImage readImage(String path) {
try {
return ImageIO.read(new File(path));
} catch (IOException e) {
throw new RuntimeException(e); // not checked = needs no try/catch
}
}
private static int[] toChannelLastBits(BufferedImage img) {
int[] bits = new int[img.getWidth() * img.getHeight() * 3];
for (int y = 0, pos = 0; y < img.getHeight(); y++) {
for (int x = 0; x < img.getWidth(); x++) {
int pixel = img.getRGB(x, y);
bits[pos++] = (pixel >> 16) & 1; // red
bits[pos++] = (pixel >> 8) & 1; // green
bits[pos++] = pixel & 1; // blue
}
}
return bits;
}
private static String decode1(int[] bits) {
int len = getAsInt(bits, 2, 18) >> 3;
char[] message = new char[len];
for (int i = 0; i < len; i++)
message[i] = (char) getAsInt(bits, 18 + (i << 3), 26 + (i << 3));
return new String(message);
}
private static BufferedImage decode2(int[] bits) {
int w = getAsInt(bits, 2, 18);
int h = getAsInt(bits, 18, 34);
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
for (int y = 0, i = 34; y < h; y++)
for (int x = 0; x < w; x++)
img.setRGB(x, y, -bits[i++]); // -1 = 0xfff... => white
return img;
}
private static int getAsInt(int[] bits, int from, int to) {
int r = 0;
for (int i = from; i < to; i++)
r = (r << 1) | bits[i];
return r;
}
publicprivate static void showImage(BufferedImage img) {
ImageIcon icon = new ImageIcon(img);
JLabel label = new JLabel(icon);
JFrame frame = new JFrame("Image Display");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(label);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}