libvips / libvips

A fast image processing library with low memory needs.
https://libvips.github.io/libvips/
GNU Lesser General Public License v2.1
9.64k stars 666 forks source link

The affine function in the VImage class is only declared but not implemented. #4102

Closed lixiang19870818 closed 1 month ago

lixiang19870818 commented 1 month ago

Hi,

I am looking for a way to build a short program (compile and link) that uses the VIPS C++ API library. The program is C++ Console Application build under QtCreator project, mingw, in Windows 10 64bit station.

I downloaded the vips-dev-w64-all-8.15.3.zip - It has a complete set of header/lib/dll folders for VIPS. All these folders were copied to the project directory.

#include <vips/vips8>
using namespace vips;
#define M_PI 3.14159265358979323846
VImage fanEffect(VImage &image, double angle)
{
    const int h = image.height();
    const int w = image.width();
    const double alpha_step = angle / w * M_PI / 180.0;

    // 创建一个仿射变换矩阵
    std::vector<double> matrix = {
        std::cos(alpha_step), -std::sin(alpha_step), 0,
        std::sin(alpha_step), std::cos(alpha_step), 0
    };

    // 使用VIPS的仿射变换函数
    VImage result = image.affine(matrix, VImage::option()->set("interpolate", VInterpolate::new_from_name("bicubic")));

    return result;
}

void applyFilter(VImage &image)
{
    image = image.gaussblur(2);
    image = image.hist_equal(); // 高动态范围处理
}

int main(int argc, char *argv[])
{
    if (VIPS_INIT (argv[0]))
        vips_error_exit (NULL);

    try
    {
        if (argc != 2)
            throw (VError ("args: <filename>"));

        VImage fred = VImage::new_from_file (argv[1]);

        printf ("Hello World!\nPixel average of %s is %g\n", argv[1],
               fred.avg ());
    }
    catch (const VError & e)
    {
        printf ("%s\n", e.what ());
    }
    return 0;
}
QT -= core
CONFIG += c++17 cmdline
SOURCES += \
        main.cpp

VIPSPATH = $$PWD/thirdparty/vips-dev-w64-all-8.15.3
INCLUDEPATH += $$PWD/thirdparty/zstd/win/x64/include
INCLUDEPATH += $$VIPSPATH/include
INCLUDEPATH += $$VIPSPATH/include/glib-2.0
INCLUDEPATH += $$VIPSPATH/lib/glib-2.0/include
DEPENDPATH += $$VIPSPATH/include
LIBS += -L$$VIPSPATH/lib/ -llibvips.dll -llibvips-cpp.dll -llibgobject-2.0.dll -llibglib-2.0.dll
C:\Qt\5.15.2\mingw81_64\bin\qmake.exe -o Makefile ..\libvipsTest\libvipsTest.pro -spec win32-g++ 
"CONFIG+=debug" "CONFIG+=qml_debug"
C:/Qt/Tools/mingw810_64/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory 'D:/worksapce/CQt/build-libvipsTest-Desktop_Qt_5_15_2_MinGW_64_bit-Debug'
g++ -c -fno-keep-inline-dllexport -g -std=gnu++1z -Wall -Wextra -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_QML_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB 
-I..\libvipsTest -I. -ID:/worksapce/CQt/libvipsTest/thirdparty/zstd/win/x64/include 
-I..\libvipsTest\thirdparty\vips-dev-w64-all-8.15.3\include 
-I..\libvipsTest\thirdparty\vips-dev-w64-all-8.15.3\include\glib-2.0 
-I..\libvipsTest\thirdparty\vips-dev-w64-all-8.15.3\lib\glib-2.0\include 
-IC:\Qt\5.15.2\mingw81_64\include 
-IC:\Qt\5.15.2\mingw81_64\include\QtGui 
-IC:\Qt\5.15.2\mingw81_64\include\QtANGLE 
-IC:\Qt\5.15.2\mingw81_64\include\QtCore -Idebug 
-I/include -IC:\Qt\5.15.2\mingw81_64\mkspecs\win32-g++  -o debug\main.o ..\libvipsTest\main.cpp
..\libvipsTest\main.cpp: In function 'vips::VImage fanEffect(vips::VImage&, double)':
..\libvipsTest\main.cpp:5:15: warning: unused variable 'h' [-Wunused-variable]
     const int h = image.height();
               ^
g++ -Wl,-subsystem,console -mthreads -o debug\libvipsTest.exe debug/main.o  
-LD:\worksapce\CQt\libvipsTest\thirdparty\vips-dev-w64-all-8.15.3\lib 
D:\worksapce\CQt\libvipsTest\thirdparty\vips-dev-w64-all-8.15.3\lib\libvips.dll.a 
D:\worksapce\CQt\libvipsTest\thirdparty\vips-dev-w64-all-8.15.3\lib\libvips-cpp.dll.a 
D:\worksapce\CQt\libvipsTest\thirdparty\vips-dev-w64-all-8.15.3\lib\libgobject-2.0.dll.a
D:\worksapce\CQt\libvipsTest\thirdparty\vips-dev-w64-all-8.15.3\lib\libglib-2.0.dll.a 
C:\Qt\5.15.2\mingw81_64\lib\libQt5Gui.a C:\Qt\5.15.2\mingw81_64\lib\libQt5Core.a   
debug/main.o: In function `fanEffect(vips::VImage&, double)':
D:\worksapce\CQt\build-libvipsTest-Desktop_Qt_5_15_2_MinGW_64_bit-Debug/../libvipsTest/main.cpp:16: 
undefined reference to `vips::VImage::affine(std::vector<double, std::allocator<double> >, vips::VOption*)  #const'
collect2.exe: error: ld returned 1 exit status
mingw32-make[1]: *** [Makefile.Debug:68: debug/libvipsTest.exe] Error 1
mingw32-make[1]: Leaving directory 'D:/worksapce/CQt/build-libvipsTest-Desktop_Qt_5_15_2_MinGW_64_bit-Debug'
mingw32-make: *** [Makefile:45: debug] Error 2

The crux of the problem is that the above error occurs at compile time only when using the affine function in the VImage class;

jcupitt commented 1 month ago

Hello @lixiang19870818,

The DLLs we ship for the libvips C++ binding on windows are built with g++10. C++ compilers all have different ABIs, so you can't mix compilers in a project. This means you must build your whole project with g++10 if you want to use them.

If you want to use a different compiler, you need to rebuild the libvips C++ binding yourself. It's pretty easy, just copy these files:

https://github.com/libvips/libvips/tree/master/cplusplus

into your project.

You don't need to rebuild the whole of libvips, just this one small C++ DLL.

lixiang19870818 commented 1 month ago

Hello @jcupitt ,

Are you sure it's caused by ABI incompatibility due to different compiler versions? But currently in my use I only have problems with compilation errors when using the affine function. If it's an ABI incompatibility, then the same problem should occur with other functions, right?

jcupitt commented 1 month ago

Ah I'm so sorry, I hadn't noticed, you are using mingw, it might be OK.

Do you know which compiler version you have?

jcupitt commented 1 month ago

You have:

D:\worksapce\CQt\libvipsTest\thirdparty\vips-dev-w64-all-8.15.3\lib\libvips.dll.a 
D:\worksapce\CQt\libvipsTest\thirdparty\vips-dev-w64-all-8.15.3\lib\libvips-cpp.dll.a 

I would swap these two -- you need libvips-cpp.dll first.

lixiang19870818 commented 1 month ago

Hello @jcupitt

Use mingw information as follows: cmd_5iyWekKrm3

The libvips.dll.a and libvips-cpp.dll.a libraries have been reordered, but the problem persists.

kleisauke commented 1 month ago

The latest libvips Windows binaries were build with Clang 18.1.8, so this sounds a libc++ versus libstdc++ ABI issue. You'll probably need to recompile the C++ binding to fix this.