ImageMagick - MAGICK_CODER_MODULE_PATH 测试结果, 很受伤

时间:2023-12-18 23:21:38

//通过查看 ImageMagick 源代码: http://code.metager.de/source/xref/ImageMagick/MagickCore/module.c#552

//首先会查找:  module_path=GetEnvironmentValue("MAGICK_CODER_MODULE_PATH");  也就是 -> getenv("MAGICK_CODER_MODULE_PATH");  读取系统变量

整个测试分两部分, 首先测试通过设置[环境变量]:MAGICK_CODER_MODULE_PATH

//关于修改[环境变量]的说明

//putenv()用来改变或增加环境变量的内容。参数envvar的格式为envvar=value,如果该环境变量原先存在,则变量内容会依参数envvar改变,

//否则此参数内容会成为新的环境变量, 返回值: 执行成功则返回0,有错误发生则返回-1: 无法配置新的环境变量空间

//注意:设置的环境仅对程序本身有效(目测对进程中已经加载的dll也无效)。

//你在程序里做的改变不会反映到外部环境中,这是因为变量的值不会从子进程传播到父进程,这样做更安全。

//但是: 子进程继承父进程的环境变量 (默认情况下,子进程继承父进程环境变量内存块的一份拷贝)

//最后说明: 通过在 xp 和 win8.1 上测试表明:

//在 xp 下测试, 通过设置  MAGICK_CODER_MODULE_PATH (使用完整路径后), 不再需要 SetCurrentDirectory(app_folder_path); 就能正常的加载宝贝图片

//在 win8.1 下测试, 通过设置  MAGICK_CODER_MODULE_PATH (使用完整路径后),  在不使用 SetCurrentDirectory(app_folder_path); 的情况下, 还是发生错误:

//image.c unknow 916 NoDecodeDelegateForThisImageFormat 'JPEG' @ error/constitute.c/ReadImage/501

//从这个结果看, 在程序中设置 环境变量 MAGICK_CODER_MODULE_PATH 没任何意义, 与使用注册表的结果是一样的, 解决不了部分win8.1上只能在英文文件夹中运行软件.

/*

char *pMagickCoderModulePath = getenv("MAGICK_CODER_MODULE_PATH");

if(pMagickCoderModulePath == NULL)

{

char coders_gbk[] = "D:\\soft\\c\\....\\bin\\Release\\modules\\coders";

int coders_gbk_len = strlen(coders_gbk);

int coders_utf8_len = coders_gbk_len * 2;

char coders_utf8[coders_utf8_len];

size_t outedSize;

iconvStr("gbk", "utf-8", coders_gbk, coders_gbk_len, coders_utf8, coders_utf8_len, &outedSize);

char text[4096];

sprintf(text, "MAGICK_CODER_MODULE_PATH=%s", coders_utf8);

//putenv("MAGICK_CODER_MODULE_PATH=modules\\coders");  //也可以使用相对路径, 但必须 SetCurrentDirectory(app_folder_path);

putenv(text);

char exeFilePath[MAX_PATH];

int len = GetModuleFileName(NULL, exeFilePath, MAX_PATH); //Long,如执行成功,返回复制到lpFileName的实际字符数量, 零表示失败。

if(len > 0)

{

printf("exeFilePath:%s\n", exeFilePath);

int status = (int)ShellExecute(NULL, "open", exeFilePath, NULL, NULL, SW_SHOW); //使用默认程序打开

printf("status:%d\n", status);

//system("pause");

exit(0);

}

}

else

{

printf("MAGICK_CODER_MODULE_PATH:%s\n", getenv("MAGICK_CODER_MODULE_PATH"));

}

*/

然后测试通过注册表:

/*

[HKEY_CURRENT_USER\SOFTWARE\ImageMagick\6.8.9\Q:16]

"BinPath"="C:\\ImageMagick"        //经过测试发现: BinPath 参数不必需, 可以没有

"ConfigurePath"="C:\\ImageMagick"  //经过测试发现: ConfigurePath 参数不必需, 可以没有

"LibPath"="C:\\ImageMagick"        //经过测试发现: LibPath 参数不必需, 可以没有

"CoderModulesPath"="C:\\ImageMagick\\modules\\coders"   //经过测试发现: 这个路径要么是相对路径, 如果是绝对路径, 必须是 utf-8编码的

"FilterModulesPath"="C:\\ImageMagick\\modules\\filters" //经过测试发现: 这个路径要么是相对路径, 如果是绝对路径, 必须是 utf-8编码的

*/

//关于 CoderModulesPath 和 FilterModulesPath 参数, 在 xp 下, 使用完整路径(utf-8), 不再需要 SetCurrentDirectory(app_folder_path);

//但是在 win8.1 下测试, 使用完整路径(utf-8) 加载宝贝失败,错误信息:

//UnableToLoadModule 'C:\....\涓诲浘瑙嗛v6.0\modules\coders\IM_MOD_RL_JPEG_.dll:找不到指定的模块 (注: 涓诲浘瑙嗛 其实就是 中文文件夹的 utf-8编码

//这个错误信息看, 在 xp,2003系统下, ImageMagick 在加载dll的时候, 先将 utf-8 编码转换成 gbk, 然后就能能正常加载对应的dll文件

//但在 win8.1 下, 没有对 utf-8编码 进行转码, 直接加载, 导致 dll 找不到

//在 win8.1 下加上 SetCurrentDirectory(app_folder_path);  又能正常的加载宝贝了。

通过两种方式的测试结果可以看出:

ImageMagick 内部加载 coder module 的代码实现是很奇葩的。

不管是通过设置环境变量:MAGICK_CODER_MODULE_PATH,还是注册表项:CoderModulesPath

如果coders 使用经过 utf-8 编码后的完整路径, 在 xp, 2003 下,不需要 SetCurrentDirectory(app_folder_path); 就能正常的加载相关的dll,但是在 win8.1 下,必需  SetCurrentDirectory(app_folder_path);

并且在极少一部分 64位的 win8.1 下, 就算 SetCurrentDirectory(app_folder_path); 也不行,必须把整个软件放在[全是英文文件夹路径]中才能正常的加载dll处理图片。

使用相对路径:modules\coders 结合 SetCurrentDirectory(app_folder_path); 在极少部分64位的win8.1 上还是出现问题,必须存放在[全是英文文件夹路径]中才能正常的加载dll处理图片。

还有一种解决办法:

对 ImageMagick 的源代码进行重新编译,生成一个静态的链接库。

这样有可能会解决所有问题, 但是生成的exe文件会很大,至少 5M+

参考:http://blog.csdn.net/wwwsq/article/details/7352777

2015-04-16