如何在Delphi 7中用GhostScript DLL转JPG为PDF?代码生成空PDF
Delphi7中GhostScript转换JPEG为PDF生成空文件的问题排查
我在网上查阅并测试了大量相关方案,但均未解决问题。我需要在Delphi 7中使用GhostScript DLL将JPEG转换为PDF文件,不过下方的代码生成的是空PDF文件,恳请大家帮忙排查问题!
function Jpg_to_Pdf(dir, inJpg, outPdf: String): Integer; const GS_ARG_ENCODING_LOCAL = 0; GS_ARG_ENCODING_UTF8 = 1; e_Quit = -990; var code, code1, gsargc, i: Integer; gsargvT: array of pansichar; gsargv: array of pansichar; minst: PGSAPIrevision; files:array of ansiString; begin setlength(gsargvT, length(gsargvT) + 1); gsargvT[high(gsargvT)] := 'gs'; setlength(gsargvT, length(gsargvT) + 1); gsargvT[high(gsargvT)] := '-dBATCH'; setlength(gsargvT, length(gsargvT) + 1); gsargvT[high(gsargvT)] := '-dNOPAUSE'; setlength(gsargvT, length(gsargvT) + 1); gsargvT[high(gsargvT)] := '-q'; setlength(gsargvT, length(gsargvT) + 1); gsargvT[high(gsargvT)] := '-sDEVICE=pdfwrite'; setlength(gsargvT, length(gsargvT) + 1); gsargvT[high(gsargvT)] := Pchar(ansiToUtf8('-sOutputFile='+dir+outPdf)); setlength(gsargvT, length(gsargvT) + 1); gsargvT[high(gsargvT)] :='viewjpeg.ps'; setlength(gsargvT, length(gsargvT) + 1); gsargvT[high(gsargvT)] := Pchar(ansiToUtf8('-c '+dir+injpg)); setlength(gsargvT, length(gsargvT)); gsargc := length(gsargvT); for i := Low(files) to High(files) do begin setlength(gsargv, length(gsargv) + 1); gsargv[high(gsargv)] := pansichar(files[i]); end; gsargc := length(gsargvT); code := gsapi_new_instance(@minst, nil); if (code < 0) then exit; code := gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8); if (code = 0) then code := gsapi_init_with_args(minst, gsargc, @gsargvT[0]); code1 := gsapi_exit(minst); if ((code = 0) or (code = e_Quit)) then code := code1; gsapi_delete_instance(minst); end;
问题排查与修正方案
1. -c参数用法错误
-c用于执行PostScript命令,直接传入文件路径不会触发JPEG的渲染逻辑。必须用PostScript语法加载JPEG并执行showpage命令,否则GhostScript不会生成任何页面,最终输出空PDF。正确格式应为:-c "(%s) viewJPEG showpage",其中%s是JPEG文件的完整路径。
2. viewjpeg.ps路径缺失
如果viewjpeg.ps不在GhostScript默认搜索路径(通常是安装目录下的lib文件夹),必须指定完整路径,否则GhostScript无法找到解析JPEG的PostScript库,转换会失败。
3. 字符串编码内存问题
Delphi7中AnsiToUtf8返回临时字符串,直接转PChar会导致内存泄漏或无效指针。应先将转换后的字符串存入局部变量,再取指针。
4. 无用代码干扰
遍历files数组的代码完全多余,files从未被初始化赋值,直接删除即可。
修正后的代码示例
function Jpg_to_Pdf(dir, inJpg, outPdf: String): Integer; const GS_ARG_ENCODING_LOCAL = 0; GS_ARG_ENCODING_UTF8 = 1; e_Quit = -990; var code, code1, gsargc: Integer; gsargvT: array of PAnsiChar; minst: PGSAPIrevision; strOutput, strJpgCmd, strViewJpegPath: AnsiString; begin Result := -1; // 初始化参数数组 SetLength(gsargvT, 0); // 基础GhostScript参数 SetLength(gsargvT, Length(gsargvT) + 1); gsargvT[High(gsargvT)] := 'gs'; SetLength(gsargvT, Length(gsargvT) + 1); gsargvT[High(gsargvT)] := '-dBATCH'; SetLength(gsargvT, Length(gsargvT) + 1); gsargvT[High(gsargvT)] := '-dNOPAUSE'; SetLength(gsargvT, Length(gsargvT) + 1); gsargvT[High(gsargvT)] := '-q'; SetLength(gsargvT, Length(gsargvT) + 1); gsargvT[High(gsargvT)] := '-sDEVICE=pdfwrite'; // 处理输出文件路径,避免内存问题 strOutput := '-sOutputFile=' + AnsiString(dir + outPdf); SetLength(gsargvT, Length(gsargvT) + 1); gsargvT[High(gsargvT)] := PAnsiChar(strOutput); // 指定viewjpeg.ps的完整路径,根据实际安装目录修改 strViewJpegPath := 'C:\Program Files\gs\gs9.55.0\lib\viewjpeg.ps'; SetLength(gsargvT, Length(gsargvT) + 1); gsargvT[High(gsargvT)] := PAnsiChar(strViewJpegPath); // 构造正确的PostScript命令:加载JPEG并生成页面 strJpgCmd := '-c "(' + AnsiString(dir + inJpg) + ') viewJPEG showpage"'; SetLength(gsargvT, Length(gsargvT) + 1); gsargvT[High(gsargvT)] := PAnsiChar(strJpgCmd); gsargc := Length(gsargvT); // 创建GhostScript实例 code := gsapi_new_instance(@minst, nil); if (code < 0) then Exit; // 设置编码格式 code := gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8); if (code = 0) then code := gsapi_init_with_args(minst, gsargc, @gsargvT[0]); // 退出并清理实例 code1 := gsapi_exit(minst); if ((code = 0) or (code = e_Quit)) then code := code1; gsapi_delete_instance(minst); Result := code; end;
额外注意事项
- 确保项目已正确加载对应版本的GhostScript DLL(32位用
gsdll32.dll,64位用gsdll64.dll),建议使用9.x稳定版。 - 检查输入JPEG和输出PDF的路径是否正确,路径含特殊字符时需确保编码处理无误。
- 调试时可移除
-q参数,查看GhostScript的输出日志,快速定位错误原因。
内容的提问来源于stack exchange,提问作者Zink
相关产品推荐
相关产品推荐

