disintegration / imaging

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

resize image become bigger #154

Open hyzgh opened 2 years ago

hyzgh commented 2 years ago

I want to resize the image to make the size smaller. But I'm suprised to find that the image becomes bigger after resizing. My code:

import (
    "bytes"
    "fmt"
    "github.com/disintegration/imaging"
    "github.com/sirupsen/logrus"
    "image"
    "io/ioutil"
    "os"
    "testing"
)

func TestResizeImage(t *testing.T) {
    srcFile := "./logo-PHOENIX.png"
    outExt := ".png"

    imgData, err := ioutil.ReadFile(srcFile)
    if err != nil {
        t.Fatal(err)
    }
    src, err := imaging.Decode(bytes.NewReader(imgData), imaging.AutoOrientation(true))
    if err != nil {
        t.Fatal(err)
    }

    srcFi, err := os.Stat(srcFile)
    if err != nil {
        t.Fatal(err)
    }
    logrus.Infof("srcFile: %v, size: %v", srcFile, srcFi.Size())

    width := []int{120, 360, 480, 720, 850, 1280}
    for _, w := range width {
        dst := ResizeImage(src, w, w)

        outFile := fmt.Sprintf("testdata/larger_%vx%v%v", w, w, outExt)

        err = imaging.Save(dst, outFile, imaging.JPEGQuality(70))
        if err != nil {
            t.Fatal(err)
        }

        fi, err := os.Stat(outFile)
        if err != nil {
            t.Fatal(err)
        }
        logrus.Infof("outFile: %v, size: %v", outFile, fi.Size())
    }
}

func ResizeImage(srcImg image.Image, width, height int) image.Image {
    isResize, height, width := calcSize(srcImg.Bounds().Dx(), srcImg.Bounds().Dy(), width, height)
    if isResize {
        srcImg = resizeImageCore(srcImg, height, width)
    }
    return srcImg
}

func calcSize(originalWidth int, originalHeight int, targetWidth int, targetHeight int) (bool, int, int) {
    if originalWidth <= targetWidth && originalHeight <= targetWidth {
        return false, originalHeight, originalWidth
    }

    var temWidth = float32(originalWidth)
    var temHeight = float32(originalHeight)
    if originalWidth > targetWidth {
        temWidth = float32(targetWidth)
        temHeight = (float32(targetWidth) / float32(originalWidth)) * float32(originalHeight)
    }
    if int(temHeight) > targetHeight {
        temWidth = (float32(targetHeight) / float32(temHeight)) * float32(temWidth)
        temHeight = float32(targetHeight)
    }
    return true, int(temHeight), int(temWidth)
}

func resizeImageCore(img image.Image, thumbnailHeight int, thumbnailWeight int) image.Image {
    return imaging.Resize(img, thumbnailWeight, 0, imaging.Lanczos)
}

output:

=== RUN   TestResizeImage
time="2021-12-15T15:13:28+08:00" level=info msg="srcFile: ./logo-PHOENIX.png, size: 13555"
time="2021-12-15T15:13:28+08:00" level=info msg="outFile: testdata/larger_120x120.png, size: 12946"
time="2021-12-15T15:13:28+08:00" level=info msg="outFile: testdata/larger_360x360.png, size: 43802"
time="2021-12-15T15:13:28+08:00" level=info msg="outFile: testdata/larger_480x480.png, size: 59066"
time="2021-12-15T15:13:28+08:00" level=info msg="outFile: testdata/larger_720x720.png, size: 93738"
time="2021-12-15T15:13:28+08:00" level=info msg="outFile: testdata/larger_850x850.png, size: 117574"
time="2021-12-15T15:13:28+08:00" level=info msg="outFile: testdata/larger_1280x1280.png, size: 14634"
--- PASS: TestResizeImage (0.11s)
PASS

I found that resized image is 8-bit RGBA, but the original image is 8-bit colormap.

image

Is there any way to keep the original bit mode?

The image: larger_1280x1280

MelleKoning commented 6 months ago

You are passing an option for JPEG while storing the file with a PNG extension. Which of these are you trying to achieve?