我想将任何文件转换为PNG并且还要反转该过程,所有这些都是用Java编写的。
我想对图像使用int-RGB形式,并且文件中的字节是RGB整数中的一个字节。这应该会产生一个图像。
我通过仅存储红色字节来实现这一点,但我无法弄清楚如何使用绿色和蓝色。
这是我目前使用的代码,它只使用红色,并且工作正常:
public static void fileToImage(String sourceFile, String imageFile) throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream(sourceFile));
int size = ((int) Math.sqrt(dis.available())) + 2;
BufferedImage image = new BufferedImage(size,size, BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
int red = dis.read(); // I'm using only red
int green = 0; // default
int blue = 0; // default
int rgb = (0xFF << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);
image.setRGB(x, y, rgb);
}
}
dis.close();
ImageIO.write(image, "png", new File(imageFile));
}
public static void imageToFile(String imageFile, String outputFile) throws IOException {
BufferedImage image = ImageIO.read(new File(imageFile));
DataOutputStream dos = new DataOutputStream(new FileOutputStream(outputFile));
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
int rgb = image.getRGB(x, y);
int red = (rgb >> 16) & 0xFF;
int green = (rgb >> 8) & 0xFF;
int blue = rgb & 0xFF;
dos.write(red); // I'm using only red
}
}
dos.close();
}
编辑:好的,所以我修改了代码,这里是:
public static void fileToImage(String sourceFile, String imageFile) throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream(sourceFile));
int size = ((int) Math.sqrt(dis.available())) + 2;
BufferedImage image = new BufferedImage(size,size, BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
int red = dis.read();
int green = dis.read();
int blue = dis.read();
int rgb = (0xFF << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);
image.setRGB(x, y, rgb);
}
}
dis.close();
ImageIO.write(image, "png", new File(imageFile));
}
public static void imageToFile(String imageFile, String outputFile) throws IOException {
BufferedImage image = ImageIO.read(new File(imageFile));
DataOutputStream dos = new DataOutputStream(new FileOutputStream(outputFile));
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
int rgb = image.getRGB(x, y);
int red = (rgb >> 16) & 0xFF;
int green = (rgb >> 8) & 0xFF;
int blue = rgb & 0xFF;
dos.write(red);
dos.write(green);
dos.write(blue);
}
}
dos.close();
}
这确实“有效”,但并不完全符合预期。制作的PNG中有很多黑色空间,因为我认为图像的“大小”是错误的。因此,在将PNG转换回原始文件时,它会变得比原来大得多。
编辑:我现在遇到的问题是这样的:例如,如果我使用fileToImage方法将带有以下内容的文本文件转换为PNG:hello world!然后我使用imageToFile将其转换回来,输出为:hello world!SSSSSSSSSSSSSSS(S代表“空格”,有15个) 编辑:仍然无法弄清楚这一点。这是我正在使用的:private static final int NAN = -1;
private static int readByte(DataInputStream dis) throws IOException {
int b;
try {
b = dis.readByte();
} catch (EOFException e) {
b = NAN;
}
return b;
}
public static void fileToImage(String sourceFile, String imageFile) throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream(sourceFile));
int size = ((int) Math.sqrt(dis.available())) + 2;
BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < size; y++) {
boolean finished = false;
for (int x = 0; x < size; x++) {
int alpha = 3;
int red = readByte(dis);
int green = readByte(dis);
int blue = readByte(dis);
if (red == NAN) {
alpha--;
red = 0;
}
if (green == NAN) {
alpha--;
green = 0;
}
if (blue == NAN) {
alpha--;
blue = 0;
}
int rgb = ((alpha & 0xFF) << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);
image.setRGB(x, y, rgb);
if (alpha < 3) {
finished = true;
break;
}
}
if (finished) break;
}
dis.close();
ImageIO.write(image, "png", new File(imageFile));
}
public static void imageToFile(String imageFile, String outputFile) throws IOException {
BufferedImage image = ImageIO.read(new File(imageFile));
DataOutputStream dos = new DataOutputStream(new FileOutputStream(outputFile));
for (int y = 0; y < image.getHeight(); y++) {
boolean finished = false;
for (int x = 0; x < image.getWidth(); x++) {
int rgb = image.getRGB(x, y);
int alpha = (rgb >> 24) & 0xFF;
int red = (rgb >> 16) & 0xFF;
int green = (rgb >> 8) & 0xFF;
int blue = rgb & 0xFF;
if (alpha == 0) {
finished = true;
break;
}
if (alpha >= 1) dos.write(red);
if (alpha >= 2) dos.write(green);
if (alpha == 3) dos.write(blue);
}
if (finished) break;
}
dos.close();
}
答案 0 :(得分:2)
我认为你只需稍微调整内环。一个小帮手方法会让这个东西更容易使用,我想我的草图有点难看:
int myReadByte(DataInputStream dis) {
int b;
try {
b = dis.readByte():
} catch (EOFException e) {
b = 0;
}
return b;
}
现在有了这个助手......
for (int x = 0; x < size; x++) {
int red = myReadByte(dis);
int green = myReadByte(dis);
int blue = myReadByte(dis);
int rgb = (0xFF << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);
image.setRGB(x, y, rgb);
和
for (int x = 0; x < image.getWidth(); x++) {
int rgb = image.getRGB(x, y);
int red = (rgb >> 16) & 0xFF;
int green = (rgb >> 8) & 0xFF;
int blue = rgb & 0xFF;
dos.write(red);
dos.write(green);
dos.write(blue);
}
答案 1 :(得分:0)
您的代码似乎将连续的3个字节转换为一个像素。因为你只有1/3的文件有颜色,2/3的休息是空的。
要解决这个问题,只需将文件大小除以3即可。
int size = ((int) Math.sqrt(dis.available()/3)) + 2;