Writing a Golang Image Compression Function with ChatGPT

Publish: 2023-04-21 | Modify: 2023-04-21

Recently, I was using Wails development to develop the ImgURL client. I needed to compress and upload images to improve efficiency and save time. This time, I asked ChatGPT to help me with this task.

Image

Requirements

I requested the following from ChatGPT:

Please help me write a Golang function that can receive an image path and compress it. The function should support jpg and png formats and validate the MIME type. If the image type is not jpg or png, the function should not process it. The compressed image should have the same path as the original image, for example, if the original path is /tmp/1.png, the compressed image should still be /tmp/1.png. The function should return an error.

The first code I received didn't validate the MIME type, so I asked ChatGPT to update the code:

It seems that you are checking the file extension instead of the MIME type. Please check the MIME type and return nil if it doesn't match. The compressed image should have the same path as the original image, for example, if the original path is /tmp/1.png, the compressed image should still be /tmp/1.png.

The second code provided seemed fine, but when I ran it, the image size didn't change. I asked ChatGPT about the issue:

Why is the image size not changing after I call the function?

ChatGPT admitted the mistake:

Sorry for the confusion. I found an error in the code. The http.DetectContentType method should receive the first 512 bytes of the file, not the file path. Here is the modified compressImage function.

The third code provided was the same as before, but this time it successfully compressed the image.

package main

import (
    "errors"
    "image"
    "image/jpeg"
    "image/png"
    "mime"
    "net/http"
    "os"
)

func compressImage(imagePath string) error {
    file, err := os.Open(imagePath)
    if err != nil {
        return err
    }
    defer file.Close()

    // Read the first 512 bytes of the file
    buffer := make([]byte, 512)
    _, err = file.Read(buffer)
    if err != nil {
        return err
    }
    file.Seek(0, 0)

    // Check the MIME type
    contentType := http.DetectContentType(buffer)

    var img image.Image
    var format string
    switch contentType {
    case "image/jpeg":
        img, err = jpeg.Decode(file)
        format = "jpeg"
    case "image/png":
        img, err = png.Decode(file)
        format = "png"
    default:
        return nil
    }

    if err != nil {
        return err
    }

    // Close and reopen the file for compression
    file.Close()
    file, err = os.OpenFile(imagePath, os.O_WRONLY|os.O_TRUNC, 0644)
    if err != nil {
        return err
    }
    defer file.Close()

    var opt jpeg.Options
    opt.Quality = 75 // Set compression quality to 75

    switch format {
    case "jpeg":
        err = jpeg.Encode(file, img, &opt)
    case "png":
        encoder := png.Encoder{CompressionLevel: png.BestCompression}
        err = encoder.Encode(file, img)
    }

    return err
}

func main() {
    imagePath := "/tmp/1.png"
    err := compressImage(imagePath)
    if err != nil {
        println("Error compressing image:", err.Error())
    } else {
        println("Image compressed successfully")
    }
}

The code was explained as follows:

In this function, JPEG images are compressed with lossy compression, while PNG images are compressed with lossless compression.

For JPEG images, the compression quality is set to 75 (the range is 1-100, where higher values indicate better quality but larger file sizes).

For PNG images, the function uses the best compression level (png.BestCompression). This performs lossless compression, preserving all original image information, but it may take longer to compress.

Conclusion

Using ChatGPT can indeed improve efficiency, but it should not be relied upon entirely. We still need our own discernment because the answers provided by ChatGPT are not always correct. We need to discern and guide the responses to obtain the correct answers. Treating ChatGPT as an auxiliary tool is a good approach. Additionally, we should distinguish which questions can be answered by ChatGPT and which ones we need to solve ourselves.

For those who cannot directly use ChatGPT, you can try AsBot: https://dwz.ovh/ab3iv.


Comments