gpt4 book ai didi

java - Java中的运行长度编码图像压缩

转载 作者:行者123 更新时间:2023-11-30 08:59:36 26 4
gpt4 key购买 nike

好的,我有一项大学作业,我需要使用游程编码和霍夫曼编码来压缩图像。我专注于运行长度编码 atm,因为我认为我没有时间实现霍夫曼。

我目前正在做的是传递一个缓冲图像,然后做

public byte[] byteArray(BufferedImage image){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] imageInByte = null;
try{
ImageIO.write(image, "BMP", baos);
baos.flush();
imageInByte = baos.toByteArray();
baos.close();
}catch(IOException e){
System.out.println(e.getMessage());
}

return imageInByte;
}

获取图像的字节。然后我接受它并进行实际压缩,为了做到这一点,我使用的是 stringBuffer,我很确定这是错误的,但我想不出另一种方法来做到这一点。所以代码是

public String getRunLength(){
StringBuffer dest = new StringBuffer();
for(int i =0; i < imageByteArray.length; i++){
int runlength = 1;
while(i+1 < imageByteArray.length && imageByteArray[i] == imageByteArray[i+1]){
runlength++;
i++;

}


dest.append(runlength);

dest.append(imageByteArray[i]);

}
return dest.toString();
}

我很确定我不应该转换为字符串,因为当我返回到字节时,我将获得 ascii 值而不是实际字节。但我无法弄清楚如何有效地将运行长度附加到标准字节数组(我想如果我将运行长度附加到开头,然后将字节 [i+runLength] 之后的所有内容向下移动,我想我可以做到array 中的 runLength 数量.. 但那将是非常低效的并且容易出错......可能)

然后我需要将它保存为图像,这显然目前无法正常工作,但我目前获得的代码是

 try{
File newImage = new File("Saved.png");
ImageIO.write(rleImage, "BMP", newImage);
}catch(Exception e){
System.out.println("something fucked up");
}

感谢您提供的任何帮助:)

刚刚注意到我错过了设置 rleImage 的部分,就像

 public BufferedImage stringToImage(String runLengthEncode){
ByteArrayInputStream bais = new ByteArrayInputStream(runLengthEncode.getBytes());
try{
imageRLE = ImageIO.read(new ByteArrayInputStream(runLengthEncode.getBytes()));
}catch(IOException e){

}
//decode(runLengthEncode);
if(imageRLE == null)
System.out.println("imageRLE is null");
return imageRLE;
}

最佳答案

您应该能够像使用 StringBuffer 一样使用 ByteArrayOutputStream:

public byte[] getRunLength(){
ByteArrayOutputStream dest = new ByteArrayOutputStream();
for(int i =0; i < imageByteArray.length; i++){
int runlength = 1;
while(i+1 < imageByteArray.length && imageByteArray[i] == imageByteArray[i+1]){
runlength++;
i++;

}

dest.write((byte)runlength);
dest.write((byte)imageByteArray[i]);
}
return dest.toByteArray();
}

这避免了整个转换为 char 并返回。

顺便说一句,该算法效率低下并且可能是错误的。您遍历每个字符,然后为每个字符期待字符的跨度。你不需要那样做。您已经遍历了所有字符,所以您需要做的就是记住最后一个字符是什么,并相应地执行操作。

public byte[] getRunLength(){
ByteArrayOutputStream dest = new ByteArrayOutputStream();
byte lastByte = imageByteArray[0];
int matchCount = 1;
for(int i=1; i < imageByteArray.length; i++){
byte thisByte = imageByteArray[i];
if (lastByte == thisByte) {
matchCount++;
}
else {
dest.write((byte)matchCount);
dest.write((byte)lastByte);
matchCount=1;
lastByte = thisByte;
}
}
dest.write((byte)matchCount);
dest.write((byte)lastByte);
return dest.toByteArray();
}

您会看到这只触及每个字节值一次。

关于java - Java中的运行长度编码图像压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27158610/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com