问题描述
我正在用 Java 开发一个文件压缩器,它使用 .png 格式,每个像素都有代表 2 个字节或 1 个字节的不同颜色。但是不知何故压缩时的二进制文件有点偏离(它创建了一个 log.txt 文件来比较二进制文件)但它仍然可以很好地读取颜色,我创建了 2 个名为“SingleByteCodec.txt”和“DoubleByteCodec.txt”的文本文件,在每行中的 SingleByteCodec 有一个不同的字节和颜色,在 DoubleByteCodec 中每行有 2 个字节和一种颜色。当我压缩一个txt文件然后解压缩它是结果
原文:你好世界!!你今天过得好吗?
压缩和解压后:HellllWoWod!! !今天还在犹豫吗?
这是我的代码:
主类:
package image_to_png;
import java.awt.FileDialog;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Main {
static File inputFile;
static int index = 0;
static double percent = 0;
static int percentBoost = 0;
static StringBuilder log = new StringBuilder();
public static void main(String[] args) {
JFrame f = new JFrame("Uncompress or Compress");
f.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
f.setBounds(500,200,500,500);
JButton comp = new JButton("Compress");
JButton uncomp = new JButton("Uncompress");
f.setLayout(new FlowLayout());
f.add(comp);
f.add(uncomp);
comp.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
JFrame f2 = new JFrame();
FileDialog fd = new FileDialog(f2,"select file to compress",FileDialog.LOAD);
fd.setVisible(true);
inputFile = new File(fd.getDirectory() + "\\" + fd.getFile());
JFrame f3 = new JFrame();
FileDialog fd2 = new FileDialog(f3,"select output file",FileDialog.SAVE);
fd2.setVisible(true);
File file2 = new File(fd2.getDirectory() + "\\" + fd2.getFile());
if (file2.exists()) {
}else {
try {
file2.createNewFile();
} catch (IOException e1) {
// Todo Auto-generated catch block
e1.printstacktrace();
}
}
try {
Compress.compress(inputFile,file2);
} catch (IOException e1) {
// Todo Auto-generated catch block
e1.printstacktrace();
}
}
});
uncomp.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JFrame f2 = new JFrame();
FileDialog fd = new FileDialog(f2,"select file to uncompress",FileDialog.LOAD);
fd.setVisible(true);
File file = new File(fd.getDirectory() + "\\" + fd.getFile());
JFrame f3 = new JFrame();
FileDialog fd2 = new FileDialog(f3,FileDialog.SAVE);
fd2.setVisible(true);
File file2 = new File(fd2.getDirectory() + "\\" + fd2.getFile());
if(file2.exists()) {
}else {
try {
file2.createNewFile();
} catch (IOException e1) {
// Todo Auto-generated catch block
e1.printstacktrace();
}
}
try {
Uncompress.uncompress(file,file2);
} catch (IOException e1) {
// Todo Auto-generated catch block
e1.printstacktrace();
}
}
});
f.setVisible(true);
}
}
压缩类:
package image_to_png;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import javax.imageio.ImageIO;
public class Compress {
static int arrayLength = 256;
static int arrayLength2 = 51344;
static Color[] allColors = new Color[arrayLength];
static String[] allByteCodes = new String[arrayLength];
static Color[] allColors2 = new Color[arrayLength2];
static String[] allByteCodes2 = new String[arrayLength2];
static int color = 0;
static Color c2 = new Color(1,1,1);
public static String getBinary(String filename) {
String binary = "";
StringBuilder sb = new StringBuilder();
try (BufferedInputStream is = new BufferedInputStream(new FileInputStream(filename))) {
for (int b; (b = is.read()) != -1;) {
String s = "0000000" + Integer.toBinaryString(b);
s = s.substring(s.length() - 8);
sb.append(s).append(' ');
}
} catch (FileNotFoundException e) {
System.out.println("Error,file not found");
e.printstacktrace();
} catch (IOException e) {
// Todo Auto-generated catch block
e.printstacktrace();
}
//System.out.println(sb);
binary = sb.toString();
binary = binary.replaceAll(" ","");
return binary;
}
static String arrayToString(Color[] s) {
String str = "";
for(int i = 0; i < s.length; i++) {
str = str + s[i].getRGB() + "\r\n";
}
return str;
}
public static Color getPixelSingleByte(String binary) throws FileNotFoundException {
Color c = null;
String bytes = "";
for(int i = 0; i < arrayLength; i++) {
if(allByteCodes[i].contains(binary)) {
c2 = allColors[i];
}
}
if(c2.getRGB() == new Color(1,1).getRGB()) {
System.out.println("did not reconize single bytecode for binary " + binary);
}
return c2;
}
public static Color getPixelDoubleByte(String binary) throws FileNotFoundException {
Color c = null;
String bytes = "";
for(int i = 0; i < arrayLength2; i++) {
if(allByteCodes2[i].contains(binary)) {
c2 = allColors2[i];
}
}
if(c2.getRGB() == new Color(1,1).getRGB()) {
System.out.println("did not reconize double bytecode for binary " + binary);
}
return c2;
}
public static void compress(File input,File output) throws IOException {
Scanner scan = new Scanner(new File("SingleByteCodec.txt"));
for(int i = 0; scan.hasNextLine(); i++) {
String line = scan.nextLine();
Color tempC = new Color(Integer.parseInt(line.substring(8,11)),Integer.parseInt(line.substring(11,14)),Integer.parseInt(line.substring(14)));
String tempBinary = line.substring(0,8);
allColors[i] = tempC;
allByteCodes[i] = tempBinary;
//System.out.println(line);
}
scan.close();
Scanner scan2 = new Scanner(new File("DoubleByteCodec.txt"));
for(int i = 0; scan2.hasNextLine(); i++) {
String line = scan2.nextLine();
Color tempC = new Color(Integer.parseInt(line.substring(16,19)),Integer.parseInt(line.substring(19,22)),Integer.parseInt(line.substring(22)));
String tempBinary = line.substring(0,16);
allColors2[i] = tempC;
allByteCodes2[i] = tempBinary;
//System.out.println(line);
}
scan2.close();
String binary = getBinary(input.getAbsolutePath());
FileWriter logWriter = new FileWriter("log.txt");
logWriter.write(binary);
logWriter.close();
int height = (binary.length() / 16) / 7000;
int width;
if(height == 0) {
height = 1;
width = (binary.length() / 16);
}else {
width = 7000;
height++;
}
width++;
String subStr = "";
int sub1 = 0;
int sub2 = 16;
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
int index = 0;
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
if(index % 100 == 0) {
System.out.println(index + "/" + width*height);
}
try {
subStr = binary.substring(sub1,sub2);
int c = getPixelDoubleByte(subStr).getRGB();
//System.out.println(c);
image.setRGB(x,y,c);
}catch(Stringindexoutofboundsexception e) {
try {
subStr = binary.substring(sub1,sub2 - 8);
int c = getPixelSingleByte(subStr).getRGB();
//System.out.println(c);
image.setRGB(x,c);
}catch(Stringindexoutofboundsexception e2) {
int c = new Color(255,255,255).getRGB();
image.setRGB(x,c);
}
}
index = index + 1;
sub1 = sub1 + 16;
sub2 = sub2 + 16;
//System.out.println(subStr);
}
}
ImageIO.write(image,"png",output);
System.out.println("Done!");
}
}
解压类:
package image_to_png;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.bufferedoutputstream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Scanner;
import javax.imageio.ImageIO;
public class Uncompress {
static int arrayLength = 256;
static int arrayLength2 = 51344;
static Color[] allColors = new Color[arrayLength];
static String[] allByteCodes = new String[arrayLength];
static Color[] allColors2 = new Color[arrayLength2];
static String[] allByteCodes2 = new String[arrayLength2];
static byte[] decodeBinary(String s) {
if (s.length() % 8 != 0) throw new IllegalArgumentException(
"Binary data length must be multiple of 8");
byte[] data = new byte[s.length() / 8];
for (int i = 0; i < s.length(); i++) {
char c = s.charat(i);
if (c == '1') {
data[i >> 3] |= 0x80 >> (i & 0x7);
} else if (c != '0') {
throw new IllegalArgumentException("Invalid char in binary string");
}
}
return data;
}
public static String getSingleByte(Color c) throws FileNotFoundException {
String binary = "NOBINARY";
int color = 0;
for (int i = 0; i < arrayLength; i++) {
//System.out.println(c.getRGB());
if(allColors[i].getRGB() == c.getRGB()) {
binary = allByteCodes[i];
}
}
if(binary == "NOBINARY") {
if(c.getRGB() == -1) {
}else {
//System.out.println("Could not find a bytecode for color " + c.getRGB());
return "!@#NOBINARY#@!";
}
}
return binary;
}
public static String getDoubleByte(Color c) throws FileNotFoundException {
String binary = "NOBINARY";
int color = 0;
for (int i = 0; i < arrayLength2; i++) {
//System.out.println(c.getRGB());
if(allColors2[i].getRGB() == c.getRGB()) {
binary = allByteCodes2[i];
}
}
if(binary == "NOBINARY") {
if(c.getRGB() == -1) {
}else {
//System.out.println("Could not find a bytecode for color " + c.getRGB());
return "!@#NOBINARY#@!";
}
}
return binary;
}
public static void uncompress(File input,16);
allColors2[i] = tempC;
allByteCodes2[i] = tempBinary;
//System.out.println(line);
}
scan2.close();
int index = 0;
String binary = "";
BufferedImage jzip = ImageIO.read(input);
int width = jzip.getWidth();
int height = jzip.getHeight();
boolean allDoublebyte = false;
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
index = index + 1;
if(index % 100 == 0) {
System.out.println(index + "/" + width * height);
}
String tempBinary = getDoubleByte(new Color(jzip.getRGB(x,y)));
if(tempBinary == "!@#NOBINARY#@!") {
tempBinary = getSingleByte(new Color(jzip.getRGB(x,y)));
}
binary = binary + tempBinary;
}
}
binary = binary.replaceAll("[^0-1]","");
Scanner sc = new Scanner(new File("log.txt"));
String oldBinary = sc.nextLine();
FileWriter logWriter = new FileWriter("log.txt");
logWriter.write("Old file binary: " + oldBinary + "\r\n" + "\r\n" + "New file binary: " + binary);
logWriter.close();
java.nio.file.Files.write(output.toPath(),decodeBinary(binary));
}
}
https://drive.google.com/drive/folders/1OlZ7tA2VEBPcyCjt2dPTmWEemN9ENC_C
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)