Golang исправляет неправильное форматирование jpeg EOF

#go #jpeg

#Вперед #jpeg

Вопрос:

Для некоторых изображений в формате jpeg EOI не заканчивается на xffxd9 , мой пример, который я вижу xffx00 , поэтому я пытаюсь исправить это с помощью 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, amp;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)
  

вот изображение, которое я тестирую

Комментарии:

1. Прочитайте файл в буфер, попытайтесь его декодировать. Если это не удается с этой ошибкой, добавьте недостающие байты и попробуйте декодировать его снова.

2. не могли бы вы загрузить поврежденное изображение?

3. Я атаковал изображение.

Ответ №1:

Вот довольно наивное решение, которое работает только в этом очень конкретном случае: прочитайте файл, попробуйте его декодировать. Если не удается декодировать, проверьте последние два байта и перезапишите последний, если это известный шаблон. Попробуйте декодировать его снова. В случае успеха запишите исправленные байты в новый файл.

 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' amp;amp; 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)
  }
}