问题描述
对于某些jpeg图像,EOI并非以\xff\xd9
结尾,在我的示例中,我看到的是\xff\x00
,所以我尝试使用go修复它。
f,_ := os.Open("bad.jpeg")
img,_,err := image.Decode(f)
if err != nil {
fmt.Println(err)
}
fmt.Println("successfully decoded")
opt := jpeg.Options{
Quality: 100,}
f1,_ := os.Create("good.jpeg")
jpeg.Encode(f1,img,&opt)
但是,image.Decode(f)
由于unexpected EOF
而失败,我想知道如何解决格式错误的jpeg文件的结尾问题。
使用Python,我可以简单地执行以下操作,open
和save
将自动为我修复EOI,这与Go中的任何等效方法一样?
from PIL import Image
im = Image.open("bad.jpeg")
im.save("good.jpeg",quality=100)
这是我正在测试的image
解决方法
这是一个非常幼稚的解决方案,仅适用于这种非常特殊的情况: 读取文件,尝试对其进行解码。如果解码失败,请检查最后两个字节,如果已知模式,则覆盖最后一个字节。尝试再次解码。如果成功,则将固定字节写入新文件。
package main
import (
"bytes"
"image"
_ "image/jpeg"
"io/ioutil"
)
func main() {
contents,err := ioutil.ReadFile("bad.jpeg")
if err != nil {
panic(err)
}
buffer := bytes.NewBuffer(contents)
_,_,err = image.Decode(buffer)
if err == nil {
return
}
if err.Error() != "unexpected EOF" {
panic(err)
}
// Maybe wrong End-Of-Image.
if contents[len(contents)-1] == '\x00' && contents[len(contents)-2] == '\xff' {
contents[len(contents)-1] = '\xd9'
} else {
panic("don't know what to do")
}
// Reset buffer and decode again.
buffer = bytes.NewBuffer(contents)
_,err = image.Decode(buffer)
if err != nil {
panic(err)
}
// Write fixed buffer to the new file.
err = ioutil.WriteFile("good.jpeg",contents,0644)
if err != nil {
panic(err)
}
}