Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slower PNG save operation #42

Closed
akaprasanga opened this issue Jul 11, 2019 · 7 comments
Closed

Slower PNG save operation #42

akaprasanga opened this issue Jul 11, 2019 · 7 comments
Labels
question Further information is requested

Comments

@akaprasanga
Copy link

akaprasanga commented Jul 11, 2019

Hi,
I need to save an image of dimension 4000X5000 in PNG format. Just opening a jpg file and saving it to png alone is too slow(8.874 secs) but saving the same file in V format takes 0.439 secs.
NetVips version = 1.0.7
Is there any way around to save png images quickly?
`stopwatch.Start();
string fname = @"D:\photo.jpg";
var image = NetVips.Image.NewFromFile(fname);
image.WriteToFile(@"D:\vips.v");
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);

        stopwatch2.Start();
        var image2 = NetVips.Image.NewFromFile(fname);
        image2.WriteToFile(@"D:\vips.png");
        stopwatch2.Stop();
        Console.WriteLine(stopwatch2.ElapsedMilliseconds);
        Console.ReadKey();`
@kleisauke kleisauke added the question Further information is requested label Jul 11, 2019
@kleisauke
Copy link
Owner

Why do you have to convert an image of that size to PNG? PNG is rather a slow format, and it uses deflate compression, which is even slower. If you switch to TIFF instead, it gets much quicker:

// https://commons.wikimedia.org/wiki/File:Stream_near_a_white_mountain_(Unsplash).jpg (4,000 x 5,000 pixels - 4.98 MB)
var im = Image.NewFromFile("Stream_near_a_white_mountain.jpg", access: Enums.Access.Sequential);
im.WriteToFile("x.tif", new VOption
{
    {"strip", true},
    {"compression", "jpeg"}
});

On my Windows PC it takes about 200 milliseconds with the above code. When I convert the same image to PNG it takes about 6.8 seconds (and the output size is 23 MB, which is quite a lot for a PNG image).

@akaprasanga
Copy link
Author

Thank you for your response.
Actually, storage usage is my main issue. I need to go further up to 15k x 18k images where the storage usage will be huge and I also need to use PNG for color separated layers. Looks like tradeoff of the execution time is the only option.

@kleisauke
Copy link
Owner

TIFF supports tiling, so you can have a JPG-compressed image larger than 64k x 64k pixels:

var im = Image.Black(100000, 100000);
im.WriteToFile("x.tif", new VOption
{
    {"tile", true},
    {"tile_width", 256},
    {"tile_height", 256},
    {"compression", "jpeg"}
});

This format breaks the image into (by default) 128x128 pixel tiles and compresses each one separately. The tiles are stored in a TIFF file with an index, so you can pull out individual tiles very quickly.

It may also be worth experimenting with WebP and Zstd compression in TIFF. These TIFF compression codecs will be available in libvips 8.9.

@akaprasanga
Copy link
Author

Will try with this one. Thank you!

@kleisauke
Copy link
Owner

You can also try to save without compression (deflate compression is quite slow). This results in large PNG files, so I think you'd better use the above TIFF examples:

// https://commons.wikimedia.org/wiki/File:Stream_near_a_white_mountain_(Unsplash).jpg (4,000 x 5,000 pixels - 4.98 MB)
var im = Image.NewFromFile("Stream_near_a_white_mountain.jpg", access: Enums.Access.Sequential);
im.WriteToFile("x.png", new VOption
{
    {"strip", true},
    {"compression",  0}
});

On my Windows PC it takes about 900 milliseconds with the above code. By default it will use a zlib compression level of 6, which takes about six seconds with NetVips.Native 8.8.1 (which has just been released).

Note that I made a performance gain of 800 milliseconds for the Windows binaries (it was 6.8 seconds in the previous release). This because libpng in the Windows binaries are now built with the appropriate compiler/optimizations flags, see commit:
libvips/build-win64-mxe@739f939

@kleisauke
Copy link
Owner

You might also be interested in this issue: lovell/sharp-libvips#25. See the relevant benchmarks: https://gist.github.com/kleisauke/879e3075a675c6f945dff3772d2ef0a3.

@kleisauke
Copy link
Owner

I'm closing this issue as NetVips can't do much about it. Any potential improvements can be tracked at lovell/sharp-libvips#25 or libvips/libvips#1403.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants