在Java中将任何文件转换为PNG

在Java中将任何文件转换为PNG,java,rgba,Java,Rgba,我想将任何文件转换为PNG,并反向转换过程,全部使用Java 我想为图像使用int RGB表单,并使文件中的字节成为RGB整数中的一个字节。这应该会产生一个图像 我只通过将字节存储为红色来实现这一点,但我不知道如何同时使用绿色和蓝色 这是我目前使用的代码,它只使用红色,工作正常: public static void fileToImage(String sourceFile, String imageFile) throws IOException { DataInputStream

我想将任何文件转换为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();
}
publicstaticvoidfiletoimage(stringsourcefile,stringimagefile)抛出IOException{
DataInputStream dis=新DataInputStream(新文件InputStream(sourceFile));
int size=((int)Math.sqrt(dis.available())+2;
BuffereImage=新的BuffereImage(大小,大小,BuffereImage.TYPE_INT_RGB);
对于(int y=0;y8)&0xFF;
蓝色整数=rgb&0xFF;
dos.write(红色);//我只用红色
}
}
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();
}
publicstaticvoidfiletoimage(stringsourcefile,stringimagefile)抛出IOException{
DataInputStream dis=新DataInputStream(新文件InputStream(sourceFile));
int size=((int)Math.sqrt(dis.available())+2;
BuffereImage=新的BuffereImage(大小,大小,BuffereImage.TYPE_INT_RGB);
对于(int y=0;y8)&0xFF;
蓝色整数=rgb&0xFF;
dos.write(红色);
dos.write(绿色);
dos.write(蓝色);
}
}
dos.close();
}
这确实“有效”,但并不完全符合预期。在生成的PNG中有大量的黑色空间,因为我认为图像的“大小”是错误的。因此,当将PNG翻译回原始文件时,它会比原始文件大很多


编辑:我现在遇到的问题是:例如,如果我使用fileToImage方法将包含以下内容的文本文件转换为PNG:hello world!然后我用imageToFile把它转换回来,输出是:hello world!SSSSSSSSS(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();
}
private static final int NAN=-1;
私有静态int readByte(DataInputStream dis)引发IOException{
int b;
试一试{
b=dis.readByte();
}捕获(EOFEException e){
b=NAN;
}
返回b;
}
publicstaticvoidfiletoimage(stringsourcefile,stringimagefile)引发IOException{
DataInputStream dis=新DataInputStream(新文件InputStream(sourceFile));
int size=((int)Math.sqrt(dis.available())+2;
BuffereImage=新的BuffereImage(大小,大小,BuffereImage.TYPE_INT_RGB);
对于(int y=0;y16)和0xFF;
绿色整数=(rgb>>8)&0xFF;
蓝色整数=rgb&0xFF;
如果(α=0){
完成=正确;
打破
}
如果(alpha>=1)dos.write(红色);
如果(alpha>=2)dos.write(绿色);
如果(alpha==3)dos.write(蓝色);
}
如果(完成)断裂;
}
dos.close();
}

我想你只需要稍微调整一下内环。一个小助手方法将使这件事更容易使用,虽然我确信我的草图有点难看:

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;x8)&0xFF;
蓝色整数=rgb&0xFF;
dos.write(红色);
dos.write(绿色);
dos.write(蓝色);
}

您的代码似乎将连续的3个字节转换为一个像素。因为只有1/3的文件是彩色的,其余的2/3是空的

要解决这个问题,只需将文件大小除以3

int size = ((int) Math.sqrt(dis.available()/3)) + 2;

我想将任何文件(EXE、JAR等)转换为PNG。我还想把它转换回去,到底是什么问题?你不明白什么?我不知道如何使用红色、绿色和蓝色来存储文件的字节。关于如何进行迭代,这是最让我困惑的@Voo你说它不能生成有效的PNG是什么意思?它应该将一些已转换的文件(PNG)转换回其原始形式,因此它应该生成非PNG。不符合您的预期:返回可从该输入流中读取的字节数的估计值,而无需阻塞。您可以将文件中的每个字节依次存储在R、G、B中,或者,您可以将每个字节的值复制到每个像素的R、G、B中,或者复制到任何一系列极其复杂的选项中。您希望通过将随机数据推入png来实现什么?也许在输入用完后第二次调用
DataInputStream
时,它不会重新抛出
EOFEException
——该助手可能需要更多的工作。尽管如此,我还是希望草图是有用的。我现在遇到的问题是:例如,如果我使用fileToImage方法将包含以下内容的文本文件转换为PNG:hello world!然后
int size = ((int) Math.sqrt(dis.available()/3)) + 2;