libvips/lua-vips

Working with vips_region_fetch

Closed this issue · 5 comments

I'm using OpenResty and trying to split an image to NN tiles
I'm trying to use vips_region_fetch like pyvips https://github.com/libvips/pyvips/blob/master/pyvips/vregion.py

local image = vips.Image.new_from_file(image_file, {access = "sequential"})
                
                local region = vobject.new(vips_lib.vips_region_new(image.vimage))

                local psize = ffi.new('size_t *')
                local pointer = vips_lib.vips_region_fetch(region, 0, 0, 100, 100, psize)

                if (pointer == ffi.NULL) then
                    ngx.say('unable to fetch from region')
                end  

                pointer = ffi.gc(pointer, glib_lib.g_free)
                -- local image = ffi.buffer(pointer, psize[0])

but this line local image = ffi.buffer(pointer, psize[0]) causes nginx crash

40354#40354: worker process 40357 exited on signal 11 (core dumped)

Could you give me some suggestions how i can get it working ?

Btw, i can use image:crop to split image to tiles. with your watermark example, i can merge the tiles like this

image_out = image_out:composite(
                            image_parts[i], 
                            "over", 
                            { x = x * tile_width, y = y * tile_height }
                        )

i think this way slower than vips_arrayjoin. I already tried to work with vips_arrayjoin but not success.
Could you tell me how to use vips_arrayjoin in lua ?

Hi @ptcong,

fetch is probably only useful for very small tiles, perhaps 32x32 pixels -- it's really for ML applications where you need to generate millions of tiny fragments for training.

To cut an image into tiles, I would use dzsave:

https://www.libvips.org/API/current/VipsForeignSave.html#vips-dzsave

It normally writes tiles image pyramids, but you can use it generate a single pyramid layer too:

$ time vips dzsave ../wtc.jpg x --depth one --tile-width 512 --tile-height 512 --overlap 0
real	0m0.439s
user	0m1.184s
sys	0m0.673s
$ ls x_files/0/
0_0.jpeg    1_12.jpeg   13_7.jpeg   16_17.jpeg  1_9.jpeg   4_4.jpeg   7_17.jpeg
0_10.jpeg   11_2.jpeg   13_8.jpeg   16_18.jpeg  2_0.jpeg   4_5.jpeg   7_18.jpeg
0_11.jpeg   1_13.jpeg   13_9.jpeg   16_1.jpeg   2_10.jpeg  4_6.jpeg   7_1.jpeg
0_12.jpeg   11_3.jpeg   1_3.jpeg    16_2.jpeg   2_11.jpeg  4_7.jpeg   7_2.jpeg
0_13.jpeg   1_14.jpeg   14_0.jpeg   16_3.jpeg   2_12.jpeg  4_8.jpeg   7_3.jpeg
0_14.jpeg   11_4.jpeg   14_10.jpeg  16_4.jpeg   2_13.jpeg  4_9.jpeg   7_4.jpeg
0_15.jpeg   1_15.jpeg   14_11.jpeg  16_5.jpeg   2_14.jpeg  5_0.jpeg   7_5.jpeg
0_16.jpeg   11_5.jpeg   14_12.jpeg  16_6.jpeg   2_15.jpeg  5_10.jpeg  7_6.jpeg
0_17.jpeg   1_16.jpeg   14_13.jpeg  16_7.jpeg   2_16.jpeg  5_11.jpeg  7_7.jpeg
0_18.jpeg   11_6.jpeg   14_14.jpeg  16_8.jpeg   2_17.jpeg  5_12.jpeg  7_8.jpeg
0_1.jpeg    1_17.jpeg   14_15.jpeg  16_9.jpeg   2_18.jpeg  5_13.jpeg  7_9.jpeg
0_2.jpeg    11_7.jpeg   14_16.jpeg  1_6.jpeg    2_1.jpeg   5_14.jpeg  8_0.jpeg
0_3.jpeg    1_18.jpeg   14_17.jpeg  17_0.jpeg   2_2.jpeg   5_15.jpeg  8_10.jpeg
0_4.jpeg    11_8.jpeg   14_18.jpeg  17_10.jpeg  2_3.jpeg   5_16.jpeg  8_11.jpeg
0_5.jpeg    11_9.jpeg   14_1.jpeg   17_11.jpeg  2_4.jpeg   5_17.jpeg  8_12.jpeg
0_6.jpeg    1_1.jpeg    14_2.jpeg   17_12.jpeg  2_5.jpeg   5_18.jpeg  8_13.jpeg
0_7.jpeg    12_0.jpeg   14_3.jpeg   17_13.jpeg  2_6.jpeg   5_1.jpeg   8_14.jpeg
0_8.jpeg    12_10.jpeg  14_4.jpeg   17_14.jpeg  2_7.jpeg   5_2.jpeg   8_15.jpeg
0_9.jpeg    12_11.jpeg  14_5.jpeg   17_15.jpeg  2_8.jpeg   5_3.jpeg   8_16.jpeg
10_0.jpeg   12_12.jpeg  14_6.jpeg   17_16.jpeg  2_9.jpeg   5_4.jpeg   8_17.jpeg
10_10.jpeg  12_13.jpeg  14_7.jpeg   17_17.jpeg  3_0.jpeg   5_5.jpeg   8_18.jpeg
10_11.jpeg  12_14.jpeg  14_8.jpeg   17_18.jpeg  3_10.jpeg  5_6.jpeg   8_1.jpeg
10_12.jpeg  12_15.jpeg  14_9.jpeg   17_1.jpeg   3_11.jpeg  5_7.jpeg   8_2.jpeg
10_13.jpeg  12_16.jpeg  1_4.jpeg    17_2.jpeg   3_12.jpeg  5_8.jpeg   8_3.jpeg
10_14.jpeg  12_17.jpeg  15_0.jpeg   17_3.jpeg   3_13.jpeg  5_9.jpeg   8_4.jpeg
10_15.jpeg  12_18.jpeg  15_10.jpeg  17_4.jpeg   3_14.jpeg  6_0.jpeg   8_5.jpeg
10_16.jpeg  12_1.jpeg   15_11.jpeg  17_5.jpeg   3_15.jpeg  6_10.jpeg  8_6.jpeg
10_17.jpeg  12_2.jpeg   15_12.jpeg  17_6.jpeg   3_16.jpeg  6_11.jpeg  8_7.jpeg
10_18.jpeg  12_3.jpeg   15_13.jpeg  17_7.jpeg   3_17.jpeg  6_12.jpeg  8_8.jpeg
10_1.jpeg   12_4.jpeg   15_14.jpeg  17_8.jpeg   3_18.jpeg  6_13.jpeg  8_9.jpeg
10_2.jpeg   12_5.jpeg   15_15.jpeg  17_9.jpeg   3_1.jpeg   6_14.jpeg  9_0.jpeg
10_3.jpeg   12_6.jpeg   15_16.jpeg  1_7.jpeg    3_2.jpeg   6_15.jpeg  9_10.jpeg
10_4.jpeg   12_7.jpeg   15_17.jpeg  18_0.jpeg   3_3.jpeg   6_16.jpeg  9_11.jpeg
10_5.jpeg   12_8.jpeg   15_18.jpeg  18_10.jpeg  3_4.jpeg   6_17.jpeg  9_12.jpeg
10_6.jpeg   12_9.jpeg   15_1.jpeg   18_11.jpeg  3_5.jpeg   6_18.jpeg  9_13.jpeg
10_7.jpeg   1_2.jpeg    15_2.jpeg   18_12.jpeg  3_6.jpeg   6_1.jpeg   9_14.jpeg
10_8.jpeg   13_0.jpeg   15_3.jpeg   18_13.jpeg  3_7.jpeg   6_2.jpeg   9_15.jpeg
10_9.jpeg   13_10.jpeg  15_4.jpeg   18_14.jpeg  3_8.jpeg   6_3.jpeg   9_16.jpeg
1_0.jpeg    13_11.jpeg  15_5.jpeg   18_15.jpeg  3_9.jpeg   6_4.jpeg   9_17.jpeg
1_10.jpeg   13_12.jpeg  15_6.jpeg   18_16.jpeg  4_0.jpeg   6_5.jpeg   9_18.jpeg
11_0.jpeg   13_13.jpeg  15_7.jpeg   18_17.jpeg  4_10.jpeg  6_6.jpeg   9_1.jpeg
11_10.jpeg  13_14.jpeg  15_8.jpeg   18_18.jpeg  4_11.jpeg  6_7.jpeg   9_2.jpeg
11_11.jpeg  13_15.jpeg  15_9.jpeg   18_1.jpeg   4_12.jpeg  6_8.jpeg   9_3.jpeg
11_12.jpeg  13_16.jpeg  1_5.jpeg    18_2.jpeg   4_13.jpeg  6_9.jpeg   9_4.jpeg
11_13.jpeg  13_17.jpeg  16_0.jpeg   18_3.jpeg   4_14.jpeg  7_0.jpeg   9_5.jpeg
11_14.jpeg  13_18.jpeg  16_10.jpeg  18_4.jpeg   4_15.jpeg  7_10.jpeg  9_6.jpeg
11_15.jpeg  13_1.jpeg   16_11.jpeg  18_5.jpeg   4_16.jpeg  7_11.jpeg  9_7.jpeg
11_16.jpeg  13_2.jpeg   16_12.jpeg  18_6.jpeg   4_17.jpeg  7_12.jpeg  9_8.jpeg
11_17.jpeg  13_3.jpeg   16_13.jpeg  18_7.jpeg   4_18.jpeg  7_13.jpeg  9_9.jpeg
11_18.jpeg  13_4.jpeg   16_14.jpeg  18_8.jpeg   4_1.jpeg   7_14.jpeg
1_11.jpeg   13_5.jpeg   16_15.jpeg  18_9.jpeg   4_2.jpeg   7_15.jpeg
11_1.jpeg   13_6.jpeg   16_16.jpeg  1_8.jpeg    4_3.jpeg   7_16.jpeg

So it cuts a 10k x 10k pixel JPEG into 400 tiles in 0.5s. You'll probably want to make a second pass over the output directory and rename the files.

You can use it from Lua with eg.:

image:dzsave("x", { depth = "one", tile_width = 512, tile_height = 512, overlap = 0 })

For arrayjoin, something like (untested):

images = {a, b, c, d}
joined = vips.Image.arrayjoin(images, { across = 2 })

To make a 2x2 join.

Thanks for your response.
But i don't want to save the tiles to disk
Can i get the tiles to a memory buffers then use vips_image_new_from_memory to join them to an image ?

Ah OK, Then just loop and crop to make an array of images, then arrayjoin to reassemble.

Ya, i use image:crop() and image:composite() from begining, i think use fetch can reduce time and CPU for spliting, but with around 30 tiles, i think that's fine.

Now i switch to arrayjoin as you suggested.

Thank you