how to convert jpg to pdf using ghostscript in Delphi - Stack Overflow

admin2025-04-29  1

I have read and test many things in internet about this issue with no solution. I want to convert a jpeg to pdf file usin ghostscript dll in Delphi 7.

the code below creates an empty pdf file.

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;

can someone help me? i have no idea how to fix this!

I have read and test many things in internet about this issue with no solution. I want to convert a jpeg to pdf file usin ghostscript dll in Delphi 7.

the code below creates an empty pdf file.

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;

can someone help me? i have no idea how to fix this!

Share Improve this question edited Jan 11 at 9:28 James Z 12.3k10 gold badges27 silver badges47 bronze badges asked Jan 7 at 0:42 ZinkZink 133 bronze badges 3
  • There is no code using a ghostscript DLL! – DelphiCoder Commented Jan 7 at 8:57
  • 1 You are using gsapi_* functions, which are only available from either a static or dynamic library, you certainly are not spawning a process to run the Ghostscript executable. You have not provided the stdout or stderr back channel communications from Ghostscript, nor the return code from the library calls, you should capture and supply that information. Most likely, as K J has said, you are getting an error because 'viewjpeg.ps' is a PostScript program which needs to open files on disk, (the JPEG file) and you have not granted permission to open that file, so you get an invaldfileaccess error. – KenS Commented Jan 7 at 9:45
  • 1 Also adding '-c' and doing so after viewjpeg.ps isn't going to work. '-c' means 'execute this piece of PostScript' and since the JPEG filename and path isn't valid PostScript that will throw an error too. The '-c' should be : -c "(......) viewJPEG" Where the ellipsis is the full path and filename of the JPEG file. Frankly, you should get this to work from the command line, using the Ghostscript executable, then try and reformulate it for Delphi. – KenS Commented Jan 7 at 9:51
Add a comment  | 

1 Answer 1

Reset to default -1

Before trying to use non console variants of GhostScript the best means to see how Windows needs specialised parameters is to use a CMD file for testing.

Environmental variables and permissions can be easily set for an input such as drag and drop or a simple command jpg2pdf.cmd "\file path\filename.jpg".

Here is such a test file where you need simply to set the root folder of your GhostScript installation and version of exe to replace mine.

@echo off
setlocal enabledelayedexpansion
set "GS_ROOT=C:/Users/K/Desktop/Apps/pdf/GS/gs10040"
set "GS_BIN=%GS_ROOT%/bin"
set "GS_LIB=%GS_ROOT%/lib"

REM Enforce only accepting "a path/filename.jpg"  adapt if you need different
set "input=%~dpn1.jpg"
if /i not "%input%" == "%~1" exit /b

REM adapt Windows input \ to Unix / (alternatively use \\)
set "input=!input:\=/!"

set "output=%~dpn1-out.pdf"
REM for debugging use echo "!input!" "!output!"


"%GS_BIN%/gswin32c.exe" --permit-file-read="%GS_LIB%/";"!input!" -sDEVICE=pdfwrite  -o"!output!" "%GS_LIB%/viewjpeg.ps" -c "(!input!) viewJPEG showpage"
if %errorlevel% == 0 exit /b
echo Error in call see above
pause & exit /b

Once you have a minimal set of command line options you can run similar in the GS# GSAPI console to see what errors that raises. This actually raised many error message fails before this worked.

Then finally port that working code to any compiler environment.

Edit

I forgot to mention that one JPEG embedded in a PDF page is so basic you don't need GhostScript, just Windows cmd can do that if you know its dimensions. For an example I prepared earlier (you can perhaps adapt in Delphi) see: https://github.com/GitHubRulesOK/MyNotes/raw/master/jpgTOpdf.zip

jpgTOpdf.bat

This is a proof of concept to show how native Windows can write JPEG to PDF. Simply drop the included GridQRcode.jpg which is a sample of a "Pixel Perfect" JPG onto jpgTopdf.bat.

There is also an example of using Windows JScript that is more versatile for third-party calling as it self-builds more than one image in its page, but needs more maths.

转载请注明原文地址:http://anycun.com/QandA/1745937143a91366.html