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