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

Allow spaces in image array filenames #1493

Closed
akemrir opened this issue Dec 6, 2019 · 18 comments
Closed

Allow spaces in image array filenames #1493

akemrir opened this issue Dec 6, 2019 · 18 comments

Comments

@akemrir
Copy link

akemrir commented Dec 6, 2019

I am trying to composite few images, but I need to use paths with spaces. How Can I escape them to use with vips command line?

Standard shell space escaping is not working.
vips composite "backgrounds\ additional/top.png backgrounds\ additional/bottom.png central.png" out.png 2 --x "3 10" --y "1 20"

This command is not working either, because vips splits array by spaces.
vips composite "backgrounds additional/top.png backgrounds additional/bottom.png central.png" out.png 2 --x "3 10" --y "1 20"

This command is not working, becuase ' is used explicitly
vips composite "'backgrounds additional/top.png' 'backgrounds additional/bottom.png' central.png" out.png 2 --x "3 10" --y "1 20"

@jcupitt
Copy link
Member

jcupitt commented Dec 6, 2019

Sorry, I don't think that's possible at the libvips CLI right now. You'll need to use something like Python.

Let's leave this issue open as an enhancement.

@jcupitt jcupitt changed the title Array of images usage Allow spaces in image array filenames Dec 6, 2019
@jcupitt
Copy link
Member

jcupitt commented Dec 6, 2019

(something like python, php, ruby, etc. should give you much better performance and IO behaviour too, so it might be worth investigating anyway)

@akemrir
Copy link
Author

akemrir commented Dec 6, 2019

I`ll try out ruby-vips.
But in case of enhancements to this in CLI, maybe a way to choose separator will do the job?

@jcupitt
Copy link
Member

jcupitt commented Dec 6, 2019

Supporting \ as an escape character in strings should be simple. It's just this function:

https://github.com/libvips/libvips/blob/master/libvips/iofuncs/type.c#L1292

@akemrir
Copy link
Author

akemrir commented Dec 9, 2019

Similar problem I`ve experienced when I wanted to use vips write_to_file.
I was forced to use write_to_buffer and then write to file with custom code.

But ruby-vips worked as intended, I achieved solution

@jcupitt
Copy link
Member

jcupitt commented Dec 9, 2019

vips_image_write_to_file should be fine -- I tried this:

/* compile with:
 *      gcc try305.c -g -Wall `pkg-config vips --cflags --libs`
 */

#include <vips/vips.h>

#define SIZE (100)

int
main( int argc, char **argv )
{
        VipsImage *image;
        int x, y, z;
        VipsPel *mem;

        if( VIPS_INIT( argv[0] ) )
                vips_error_exit( NULL );

        /* SIZE x SIZE rgba image.
         */
        if( !(mem = VIPS_ARRAY( NULL, 4 * SIZE * SIZE, VipsPel )) )
                vips_error_exit( NULL );
        for( y = 0; y < SIZE; y++ )
                for( x = 0; x < SIZE; x++ )
                        for( z = 0; z < 4; z++ )
                                mem[y * 4 * SIZE + x * 4 + z] = 2 * (x + y + z);

        /* Wrap up as a 4-band VipsImage.
         */
        if( !(image = vips_image_new_from_memory( mem, 4 * SIZE * SIZE,
                SIZE, SIZE, 4, VIPS_FORMAT_UCHAR )) )
                vips_error_exit( NULL );

        if( vips_image_write_to_file( image, 
                "this is a filename with spaces.png", NULL ) )
                vips_error_exit( NULL );

        g_object_unref( image );

        g_free( mem );

        return( 0 );
}

I see:

john@kiwi:~/try$ ./a.out 
john@kiwi:~/try$ ls this\ is\ a\ filename\ with\ spaces.png 
'this is a filename with spaces.png'

@akemrir
Copy link
Author

akemrir commented Dec 16, 2019

Yes, that's the case.

jcupitt added a commit that referenced this issue Jan 26, 2020
So:

	vips_break_token( "hello\ world", " " )

Sees a single token, `"hello world"`.

This means you can now do things like:

	$ vips arrayjoin "k\ 2.jpg" x.png

Where "k 2.jpg" is a filename containing a space.

See #1493
@jcupitt
Copy link
Member

jcupitt commented Jan 26, 2020

OK, this works now:

vips arrayjoin "k\ 2.jpg" x.png

Where "k 2.jpg" is a filename containing a space. You can escape break characters everywhere, so:

vips copy x.png y.jpg[profile=a\,b.icc,Q=50]

Sets a profile from a file called "a,b.icc".

Thanks for the suggestion!

@jcupitt jcupitt closed this as completed Jan 26, 2020
@akemrir
Copy link
Author

akemrir commented Jan 27, 2020

Very useful. Thanks for update.

@jddcef
Copy link

jddcef commented Oct 3, 2023

And on windows where the backslash itself is a directory seperator, how to differentiate it in the path?

@jcupitt
Copy link
Member

jcupitt commented Oct 3, 2023

You can use a double backslash, eg.:

$ vips black "x\\y.v" 10 10

@jddcef
Copy link

jddcef commented Oct 3, 2023

Hi, i'm failing to get a simple test file with a space to be found by vips...
I've tried permutations like
D:\temp\BKLXSC\1696099971.tiff
D:\temp\BKLXSC\ 1696099971.tiff
D:\temp\BKLXSC\\1696099971.tiff
D:\temp\BKLXSC\ 1696099971.tiff

etc

@jcupitt
Copy link
Member

jcupitt commented Oct 3, 2023

What's the exact command you are trying to run?

I see:

jcupi@DESKTOP-HGI6HBR MINGW64 /f/vips-dev-8.14/bin
$ ./vips.exe black "x y.jpg" 10 10

jcupi@DESKTOP-HGI6HBR MINGW64 /f/vips-dev-8.14/bin
$ ./vips.exe invert "x y.jpg" "y x.jpg"

jcupi@DESKTOP-HGI6HBR MINGW64 /f/vips-dev-8.14/bin
$ ls
 libaom.dll*                libgsf-1-114.dll*          libunwind.dll*
 libc++.dll*                libharfbuzz-0.dll*         libvips-42.dll*
 libcairo-2.dll*            libheif.dll*               libvips-cpp-42.dll*
 libcgif-0.dll*             libimagequant.dll*         libwebp-7.dll*
 libexif-12.dll*            libjpeg-62.dll*            libwebpdemux-2.dll*
 libexpat-1.dll*            liblcms2-2.dll*            libwebpmux-3.dll*
 libffi-8.dll*              liborc-0.4-0.dll*          libxml2-2.dll*
 libfontconfig-1.dll*       libpango-1.0-0.dll*        libz1.dll*
 libfreetype-6.dll*         libpangocairo-1.0-0.dll*   vips.exe*
 libfribidi-0.dll*          libpangoft2-1.0-0.dll*     vipsedit.exe*
 libgdk_pixbuf-2.0-0.dll*   libpixman-1-0.dll*         vipsheader.exe*
 libgio-2.0-0.dll*          libpng16-16.dll*           vipsthumbnail.exe*
 libglib-2.0-0.dll*         librsvg-2-2.dll*          'x y.jpg'
 libgmodule-2.0-0.dll*      libspng-0.dll*            'y x.jpg'
 libgobject-2.0-0.dll*      libtiff-6.dll*

jcupi@DESKTOP-HGI6HBR MINGW64 /f/vips-dev-8.14/bin
$

@jddcef
Copy link

jddcef commented Oct 4, 2023

powershell:
PS D:\Users\User\OneDrive\Apps> C:\Users\User\Downloads\vips-dev-w32-all-8.14.5\vips-dev-8.14\bin\vips.exe arrayjoin "D:\\temp\\BKLXSC-1696099971.tiff D:\\temp\\BKLXSC\\ 1696099971.tiff" d:\temp\blahtest.tif[lossless,compression=deflate]
and all the other variations... results in
VipsForeignLoad: file "D:\temp\BKLXSC\ 1696099971.tiff" does not exist

cmd:
C:\Users\User\Downloads\vips-dev-w32-all-8.14.5\vips-dev-8.14\bin>C:\Users\User\Downloads\vips-dev-w32-all-8.14.5\vips-dev-8.14\bin\vips.exe arrayjoin "D:\\temp\\BKLXSC-1696099971.tiff D:\\temp\\BKLXSC\\\\1696099971.tiff" d:\temp\blahtest.tif[lossless,compression=deflate]
VipsForeignLoad: file "D:\temp\BKLXSC\\1696099971.tiff" does not exist

I right clicked on the file itself to confirm its existence -> copy path, and it gives the path: "D:\temp\BKLXSC 1696099971.tiff"

vips-modules-8.14 libaom.dll libarchive-13.dll libbrotlicommon.dll libbrotlidec.dll libbrotlienc.dll libc++.dll libcairo-2.dll libcfitsio.dll libcgif-0.dll libexif-12.dll libexpat-1.dll libffi-8.dll libfftw3-3.dll libfontconfig-1.dll libfreetype-6.dll libfribidi-0.dll libgdk_pixbuf-2.0-0.dll libgio-2.0-0.dll libglib-2.0-0.dll libgmodule-2.0-0.dll libgobject-2.0-0.dll libharfbuzz-0.dll libheif.dll libhwy.dll libIex-3_1.dll libIlmThread-3_1.dll libimagequant.dll libjpeg-62.dll libjxl.dll libjxl_threads.dll liblcms2-2.dll libMagickCore-6.Q16-7.dll libmatio-11.dll libniftiio.dll libOpenEXR-3_1.dll libopenjp2.dll libopenslide-0.dll liborc-0.4-0.dll libpango-1.0-0.dll libpangocairo-1.0-0.dll libpangoft2-1.0-0.dll libpixman-1-0.dll libpng16-16.dll libpoppler-131.dll libpoppler-glib-8.dll librsvg-2-2.dll libsharpyuv-0.dll libspng-0.dll libsqlite3-0.dll libtiff-6.dll libunwind.dll libvips-42.dll libvips-cpp-42.dll libwebp-7.dll libwebpdemux-2.dll libwebpmux-3.dll libxml2-2.dll libz1.dll libznz.dll vips.exe vipsedit.exe vipsheader.exe vipsthumbnail.exe

@jcupitt
Copy link
Member

jcupitt commented Oct 4, 2023

I tried in psh as well, it all seems to work here:

PS F:\vips-dev-8.14\bin> .\vips.exe arrayjoin "x\ y.jpg y\ x.jpg" x.jpg
PS F:\vips-dev-8.14\bin> .\vipsheader.exe x.jpg "x y.jpg" "y x.jpg"
x.jpg: 20x10 uchar, 1 band, b-w, jpegload
x y.jpg: 10x10 uchar, 1 band, b-w, jpegload
y x.jpg: 10x10 uchar, 1 band, b-w, jpegload

@jcupitt
Copy link
Member

jcupitt commented Oct 4, 2023

I tried with tiffs and drive letters and that works too:

PS F:\vips-dev-8.14\bin> .\vips.exe black "f:\b a.tif" 10 10
PS F:\vips-dev-8.14\bin> .\vips.exe black "f:\b a.tif" 10 10
PS F:\vips-dev-8.14\bin> .\vips.exe arrayjoin "f:\\a\ b.tif f:\\b\ a.tif" "f:\c d.tif"
PS F:\vips-dev-8.14\bin> .\vipsheader.exe "f:\c d.tif" "f:\a b.tif" "f:\b a.tif"
f:\c d.tif: 20x10 uchar, 1 band, b-w, tiffload
f:\a b.tif: 10x10 uchar, 1 band, b-w, tiffload
f:\b a.tif: 10x10 uchar, 1 band, b-w, tiffload
PS F:\vips-dev-8.14\bin>

@jcupitt
Copy link
Member

jcupitt commented Oct 4, 2023

There are two different ways of quoting backslash and space because there are two different things interpreting them.

In plain command-line arguments, just use space and put the whole thing in quotes. PSH doesn't use backslash as escape, so you don't need to quote it:

PS F:\vips-dev-8.14\bin> .\vips.exe black "f:\b a.tif" 10 10

arrayjoin is different -- that's a string encoding a list of paths that needs to be split by libvips. It uses (*nix style) backslash as an escape character, so you do need to escape backslash as double backslash, and space as backslash-space.

PS F:\vips-dev-8.14\bin> .\vips.exe arrayjoin "f:\\a\ b.tif f:\\b\ a.tif" "f:\c d.tif"

I agree, it's confusing :( If you use something like python, all this shell craziness goes away.

@jddcef
Copy link

jddcef commented Oct 5, 2023

I came right, your examples helped, I was doing everything except the right thing, embarrassed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants