disintegration / imaging

Imaging is a simple image processing package for Go
MIT License
5.3k stars 443 forks source link

Incorrect resize image #144

Closed batazor closed 3 years ago

batazor commented 3 years ago

For some reason, the bottom part of the image was just cropped off

Type Image
Original котэ-пельмешки-еда-6639178
Resize (50xauto) preview-cNJ2haYSuSHYfxjj5udMHn
disintegration commented 3 years ago

Hi, Could you please provide the code example that produces the given result?

batazor commented 3 years ago

@disintegration Yes

I tried using png.Encode/Decode and change compression algorithms. But the result didn't change much.

file.PreviewWidth = 50

However, when I changed the width to 60, the files stopped crashing

type Settings struct {
    PreviewWidth int `envconfig:"IMG_RESIZE_PREVIEW_WIDTH"`
    MediumWidth  int `envconfig:"IMG_RESIZE_MEDIUM_WIDTH"`
}

type Image struct {
    Settings
}

type Resize struct {
    Preview []byte
    Medium  []byte
}

func (file *Image) Resize1(image io.Reader, filename string) (*Resize, error) {
    w := &bytes.Buffer{}
    _, err := io.Copy(w, image)
    if err != nil {
        return nil, err
    }

    format, err := imaging.FormatFromFilename(filename)
    if err != nil {
        return nil, err
    }

    srcImage, err := imaging.Decode(w)
    if err != nil {
        return nil, err
    }

    // Save image
    resp := &Resize{}

    var previewFile bytes.Buffer
    writerPreview := bufio.NewWriter(&previewFile)
    previewImage := imaging.Resize(srcImage, file.PreviewWidth, 0, imaging.CatmullRom)
    err = imaging.Encode(writerPreview, previewImage, format, imaging.PNGCompressionLevel(png.NoCompression))
    if err != nil {
        return nil, err
    }
    resp.Preview = previewFile.Bytes()
    err = writerPreview.Flush()
    if err != nil {
        return nil, err
    }

    return resp, nil
}
disintegration commented 3 years ago

You should flush the buffered writer before calling previewFile.Bytes(), e.g.:

err = writerPreview.Flush()
if err != nil {
    return nil, err
}
resp.Preview = previewFile.Bytes()

I believe you don't need bufio.Writer at all if you're writing to the in-memory byte buffer.