h2non / bimg

Go package for fast high-level image processing powered by libvips C library
https://pkg.go.dev/github.com/h2non/bimg?tab=doc
MIT License
2.72k stars 340 forks source link

Broken Image #361

Open kristopeltoped opened 4 years ago

kristopeltoped commented 4 years ago

Hi, guys. Have you ever faced this problem?

Original Image: image2

Result: 1b5ce631-1de8-4c6f-b951-d8496635c42e

I did some performance test (the resizing process run concurrently) which the scenario is resizing the image into 3 size: 300x300, 700x700, and 200-square, and upload the resized image to our storage.

After the performance test, I check the image 1 by 1, and found some images like I mentioned above.

Here are the options that I used to resize the image:

Thank you.

imcsorin commented 3 years ago

Are you writing images to the same buffer?

This might happen if several goroutines write an image to the same buffer before it ends processing. Try using sync.Pool if you are reusing the same buffer, it is safe to use from multiple goroutines.

kristopeltoped commented 3 years ago

Actually, I always call bimg.NewImage() everytime I want to resize an image.

Here's the flow of my script: // Create New Image bimgImage := bimg.NewImage(dataByte)

// Create Options bimgOpt := bimg.Options{ Quality: 80}

// Process imgByte, err := bimgImage.Process(bimgOpt)

cc: @sorinsi

kristopeltoped commented 3 years ago

Is my flow using the same buffer @h2non ?

imcsorin commented 3 years ago

Give this a try, paste the code somewhere outside of your method:

var bufPool = sync.Pool{
    New: func() interface{} {
        return &bytes.NewBuffer{}
    },
}

And inside your method use:

dataByte := bufPool.Get().(*bytes.Buffer)

defer func() {
    // clean stuff up
    bufPool.Reset()
    bufPool.Put(dataByte)
}

Let me know if this helps or not