Created attachment 24994 [details] xps file When XPS files are generated by a virtual printer (Microsoft XPS Document Writer), the images will not be displayed when converting xps to pdf. The attached xps file has been uploaded img base64.txt is the base64 string of the image
Created attachment 24995 [details] image base64 string
This isn't a problem with pdfwrite. Rendering the XPS file produces an empty page. If it doesn't render properly it certainly won't produce a correct PDF file from the pdfwrite device.
(In reply to Ken Sharp from comment #2) > This isn't a problem with pdfwrite. Rendering the XPS file produces an empty > page. If it doesn't render properly it certainly won't produce a correct PDF > file from the pdfwrite device. I have uploaded the xps file in the attachment, and the generated xps file is correct
(In reply to lanwah from comment #3) > (In reply to Ken Sharp from comment #2) > > This isn't a problem with pdfwrite. Rendering the XPS file produces an empty > > page. If it doesn't render properly it certainly won't produce a correct PDF > > file from the pdfwrite device. > > I have uploaded the xps file in the attachment, and the generated xps file > is correct I did not say there was a problem with the XPS file. What I said was that if you render the XPS file with GhostXPS then the result is an empty page, therefore the problem is with the XPS interpreter, not the pdfwrite device.
For the record; the problem is that the embedded JPEG image has X_Density = Y_Density = 0, ie it declares a resolution of zero dpi. If I force the code to assume 96 dpi then the images render correctly. This commit 4dc6cbedb4ef789c8c8ebd4c83095d0198050350 for MUPDF additionally reads the resolution from the EXIF and APP13 marker and uses these, possibly in preference, to get a non-zero resolution. I would guess something similar needs to be done.
(In reply to Ken Sharp from comment #5) > For the record; the problem is that the embedded JPEG image has X_Density = > Y_Density = 0, ie it declares a resolution of zero dpi. > > If I force the code to assume 96 dpi then the images render correctly. > > This commit 4dc6cbedb4ef789c8c8ebd4c83095d0198050350 for MUPDF additionally > reads the resolution from the EXIF and APP13 marker and uses these, possibly > in preference, to get a non-zero resolution. I would guess something similar > needs to be done. Thank you for your answer. I get the source image form the base64 string ,i find that the dpi is 96(attachment file 1.png). I draw the image to xps like this: Graphics.DrawImage(img2, 96, 300); I Convert the xps file to pdf file this: /// <summary> /// Converts XPS file to PDF using provided pathes. /// </summary> /// <param name="xpsFilePath">XPS file path.</param> /// <param name="pdfFilePath">PDF file path.</param> /// <param name="utilitiesPath">Path ghost xps utilities.</param> public static void Convert(string xpsFilePath, string pdfFilePath, string utilitiesPath = null) { if (string.IsNullOrEmpty(xpsFilePath)) { throw new ArgumentNullException(nameof(xpsFilePath), "Xps file path can't be empty. Please, specify a valid xps file path."); } if (string.IsNullOrEmpty(pdfFilePath)) { throw new ArgumentNullException(nameof(pdfFilePath), "Pdf file path can't be empty. Please, specify a valid pdf file path."); } var ghostStartInfo = new ProcessStartInfo { WorkingDirectory = Environment.CurrentDirectory, FileName = Environment.Is64BitOperatingSystem ? $"{utilitiesPath}gxpswin64.exe" : $"{utilitiesPath}gxpswin32.exe", Arguments = $"-dNOPAUSE -dBATCH -dSAFER -sOutputFile=\"{pdfFilePath}\" -sDEVICE=pdfwrite \"{xpsFilePath}\"", CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true }; using (var ghostProcess = Process.Start(ghostStartInfo)) { ghostProcess.WaitForExit(); if(ghostProcess.ExitCode != 0) { var message = ghostProcess.StandardError.ReadToEnd(); throw new XpsConverterException(message); } } } Another question I have is: what types of images in xps can be converted to pdf, so far I have found that only png images in xps can be converted successfully.
Created attachment 24997 [details] source picture resolution
(In reply to Ken Sharp from comment #4) > (In reply to lanwah from comment #3) > > (In reply to Ken Sharp from comment #2) > > > This isn't a problem with pdfwrite. Rendering the XPS file produces an empty > > > page. If it doesn't render properly it certainly won't produce a correct PDF > > > file from the pdfwrite device. > > > > I have uploaded the xps file in the attachment, and the generated xps file > > is correct > > I did not say there was a problem with the XPS file. > > What I said was that if you render the XPS file with GhostXPS then the > result is an empty page, therefore the problem is with the XPS interpreter, > not the pdfwrite device. Thanke you for you answer. I do nothing with the xps file. I convert the xps to pdf like this: /// <summary> /// Converts XPS file to PDF using provided pathes. /// </summary> /// <param name="xpsFilePath">XPS file path.</param> /// <param name="pdfFilePath">PDF file path.</param> /// <param name="utilitiesPath">Path ghost xps utilities.</param> public static void Convert(string xpsFilePath, string pdfFilePath, string utilitiesPath = null) { if (string.IsNullOrEmpty(xpsFilePath)) { throw new ArgumentNullException(nameof(xpsFilePath), "Xps file path can't be empty. Please, specify a valid xps file path."); } if (string.IsNullOrEmpty(pdfFilePath)) { throw new ArgumentNullException(nameof(pdfFilePath), "Pdf file path can't be empty. Please, specify a valid pdf file path."); } var ghostStartInfo = new ProcessStartInfo { WorkingDirectory = Environment.CurrentDirectory, FileName = Environment.Is64BitOperatingSystem ? $"{utilitiesPath}gxpswin64.exe" : $"{utilitiesPath}gxpswin32.exe", Arguments = $"-dNOPAUSE -dBATCH -dSAFER -sOutputFile=\"{pdfFilePath}\" -sDEVICE=pdfwrite \"{xpsFilePath}\"", CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true }; using (var ghostProcess = Process.Start(ghostStartInfo)) { ghostProcess.WaitForExit(); if(ghostProcess.ExitCode != 0) { var message = ghostProcess.StandardError.ReadToEnd(); throw new XpsConverterException(message); } } }
(In reply to lanwah from comment #6) > Thank you for your answer. > > I get the source image form the base64 string ,i find that the dpi is > 96(attachment file 1.png). It doesn't matter what the .png file says. The image in the XPS file is a JPEG, not a PNG and it has no resolution defined. It also lacks an EXIF or an APP13 marker, so the resolution genuinely is not defined. This commit f999c9ee55423d6669c396f26d68edc57c17b8cf forces an undefined resolution to be treated as 96 dpi which resolves the problem. As I noted in comment #5 above, the specification says that we should also read EXIF or APP13 markers, and the commit does not address that, so I have altered this to an enhancement, requiring that work to be done. > I draw the image to xps like this: > Graphics.DrawImage(img2, 96, 300); Doesn't matter how you create the XPS file, it is what the XPS file contains that matters. Your XPS file contains a JPEG image, not a PNG and that JPEG image does not define a resolution. > Another question I have is: what types of images in xps can be converted to > pdf, so far I have found that only png images in xps can be converted > successfully. The XPS specification is available here https://www.microsoft.com/en-us/download/details.aspx?id=51478
Enhancement completed with commit dde12cc2aab267741c52277bcb78d75f271845a5
(In reply to Ken Sharp from comment #11) > Enhancement completed with commit dde12cc2aab267741c52277bcb78d75f271845a5 Thank you for your contribution.