DEV Community

k.yamashita
k.yamashita

Posted on • Edited on

Is File Size Enough for Image Validation?

TL;DR

Image editing on the server side is a memory-intensive operation. Memory usage during image editing processes is influenced not just by file size but also by resolution. This is because the processed image data is expanded as an uncompressed bitmap in memory. To avoid memory shortages on the server, you can estimate memory consumption using the image's header information and decide to halt processing if necessary.

Verifying Memory Usage When Editing High-Resolution Images

I conducted tests to ascertain if editing high-resolution images genuinely amplifies memory usage. These tests were carried out using Go version 1.20.

Below is the sample code. In this example, a 7000×7000(6.1KB) PNG image is resized to 70×70. For comparison, an image of 4032×3024(11.7MB) in PNG format is also resized to 70×70. Using Go's "testing" package, I gauged the average memory usage when executing the associated code 100 times.

main.go

package main

import (
    "image"
    _ "image/png"
    "os"
    "github.com/disintegration/imaging"
)

// Function to resize the image
func ResizeImage(r image.Image) image.Image {
    return imaging.Resize(r, 70, 70, imaging.Lanczos)
}

func OpenAndDecodeImage(path string) (image.Image, error) {
    file, err := os.Open(path)
    if err != nil {
        return nil, err
    }
    defer file.Close()

    img, _, err := image.Decode(file)
    return img, err
}

func main() {
    // Main process
}
Enter fullscreen mode Exit fullscreen mode

main_test.go

package main

import (
    _ "image/png"
    "testing"
    "github.com/disintegration/imaging"
)

func BenchmarkResizeImage(b *testing.B) {
    for i := 0; i < b.N; i++ {
        f, openErr := OpenAndDecodeImage("7000×7000.png")
        if openErr != nil {
            b.Errorf("OpenAndDecodeImage() error = %v", openErr)
        }
        resizedImage := ResizeImage(f)
        resizeErr := imaging.Save(resizedImage, "resized.png")
        if resizeErr != nil {
            b.Errorf("imaging.Save() error = %v", resizeErr)
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

memory usage result

From these outcomes, it's evident that even though the image file size is a mere 6.1KB, it uses up around 200MB of memory.

Why it happened

Memory usage is influenced by resolution, not file size.
When loading an image into memory, the memory usage can fundamentally be estimated using:

Image data volume = width in pixels × height in pixels × data size per pixel.

Thus, it's crucial to validate using the image's pixel dimensions before completely loading it into memory.

How to ascertain pixel dimensions

For JPEG and PNG formats, the image's pixel dimensions (width and height) are encapsulated in the header information. This means the resolution can be acquired before the image is fully loaded.

Conclusion

Through this article, I hope readers grasp that image editing tasks can be heavy on memory, and solely validating based on file size won't suffice.

Top comments (0)